Sql-Server

在 SQL 中的 CASE 表達式中轉換為 int

  • February 8, 2019

我有一個從 10 個表和一個子查詢中提取數據的查詢。其中一個選擇是針對一個位置,我正在使用 case 表達式來清理輸出數據。它從中提取數據的欄位是varchar,數據可以是以下值:USA800、admin、ccc-ulw、ccc-ury、002-Carson、066-Nellis BX、042-Junction City(還有更多) .

我希望案例快遞報告一個特定值,如果它是不以數字開頭的位置之一,但如果它是一個數字,我希望它只返回數字,作為一個整數(刪除 0) .

這是我現在擁有的查詢(可能不需要整個 SQL,但我認為它會幫助上下文):

   select 
   ct.id as CaseID
   ,c.first_name as FirstName
   ,c.last_name as LastName
   ,c.id as CustomerID
   ,SUBSTRING(sdu.User_ID,CHARINDEX('-',sdu.User_ID)+1,(((LEN(sdu.User_ID))-CHARINDEX('-', REVERSE(sdu.User_ID)))-CHARINDEX('-',sdu.User_ID))) as [Username from Navigator]
   ,case sdu.Application_Name when 'Navigator' then sn.[RESP CODE] else '' end as [Responsibility Code from Navigator]
   ,case sdu.Application_Name when 'Navigator' then RIGHT(sn.[EMUL STATION], 4) else '' end as [CStat From Navigator]
   ,ce02.id as JobCode
   ,case l.id 
       when 'USA800' then 'USA800' 
       when 'admin' then 'Admin'
       when 'ccc-ulw' then 'CCC-Lawrence'
       when 'ccc-ury' then 'CCC-Raytown'
       when 'ccc-usj' then 'CCC-St Joseph'
       when 'ccc-uwf' then 'CCC-Wichita Falls'
       else cast(SUBSTRING(l.id, 0, charindex('-', l.id, 0)) as int) 
   end as location
   ,l.id
   ,c2.first_name as SubmittedByFirstName
   ,c2.last_name as SubmittedByLastName
   ,sn.INST as Institution
   ,case sdupc.Application_Name when 'PartnerCare' then sdupc.User_ID else '' end as [Partnercare Username]
from Case_Table ct 
   left join Case_Type t on t.case_type_pk = ct.case_type_pk
   left join Case_Category cc on cc.case_category_pk = ct.case_category_pk
   left join (select max(cas.case_pk) as case_pk, customer_pk from Case_Table cas join Case_Type cat on cas.case_type_pk=cat.case_type_pk where cat.id = 'ASR' group by cas.customer_pk) ce01 on ce01.case_pk = ct.case_pk
   left join Custom_Entity02 ce02 on ce02.custom_entity02_pk = ct.Virtual_JobCode
   left join Customer c on ce01.customer_pk = c.customer_pk
   left join Location l on l.location_pk = c.location_pk
   right join Customer c2 on c2.customer_pk = ct.installed_by_customer_pk
   left join Prod.dbo.Staging_DataFeed_Users sdu on sdu.User_Name = c.description and sdu.application_name = 'Navigator'
   left join Prod.dbo.Staging_DataFeed_Users sdupc on sdupc.User_Name = c.description and sdupc.application_name = 'PartnerCare'
   left join Prod.dbo.Staging_Navigator sn on sn.NAME = c.description and sn.NAME = sdu.User_Name
where t.id='ASR'

varchar執行查詢時,將value 轉換為 data type時出現轉換失敗錯誤int

要麼我錯過了一些東西,要麼有更好的方法可以做到這一點,我對想法持開放態度。

在這種情況下,客戶期望整數(他們希望它看起來像沒有前導零的整數)。

此查詢的結果用於 foxtrot 腳本,用於從應用程序中取消配置使用者,這些數字代表我們銀行系統中的分支機構。前導零會導致問題。如果結果是字元串,則將其忽略。

你為什麼首先將子字元串轉換為 int ?消費者將期望該列在其他情況下輸出為字元串。所以我的建議是:去掉演員表。

如果您只希望一個值在有效出現在結果集中int,並且您在 < 2012 上TRY_CAST()是不可能的,那麼您可以說:

else case when isnumeric(SUBSTRING(l.id, 0, charindex('-', l.id, 0))) = 1
 THEN CAST SUBSTRING(l.id, 0, charindex('-', l.id, 0)) AS int END

注意:ISNUMERIC()並不是一個完美的驗證,它特別是一個整數,但在這裡可能很好,因為你並不真的需要一個int,只是一個格式化為int.

更新既然我更好地理解了要求,您現在可以做的就是轉換為 int,然後再轉換回字元串。由於您在 2014 年,您可以使用TRY_CONVERT()

ELSE CONVERT(varchar(12), 
 TRY_CONVERT(int, SUBSTRING(l.id, 0, charindex('-', l.id, 0)))) 
END

您還可以考慮修復設計,這樣您就不必從更大的資訊中解析這些重要的資訊,或者至少將您的CASE表達式移動到計算列或視圖中,這樣您就不必將所有您的所有(或任何!)查詢中的邏輯。

如果您使用的是 SQL Server 2012 或更高版本,則可以用您CAST()的函式替換該TRY_CAST()函式。

CAST()和之間的區別在於TRY_CAST(),前者在無法轉換值時會失敗,而後者只會返回 NULL 值。NULL 值可能不是您想要的,因此您應該仔細測試此更改,以免破壞任何內容。

引用自:https://dba.stackexchange.com/questions/229262