在 SQL 中的 CASE 表达式中转换为 int

Rho*_*nda 2 sql-server cast sql-server-2014

我有一个查询,它从 10 个表和一个子查询中提取数据。其中一个选择是针对某个位置,我正在使用 case 表达式来清理输出数据。它拉取数据的字段是varchar,数据可以是这样的值:USA800, admin, ccc-ulw, ccc-ury, 002-Carson, 066-Nellis BX, 042-Junction City(还有更多) .

如果它是不以数字开头的位置之一,我希望 case express 报告一个特定值,但如果它是一个数字,我希望它只返回数字,作为一个整数(删除 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'
Run Code Online (Sandbox Code Playgroud)

运行查询时,将varchar值转换为数据类型时出现转换失败错误int

要么我遗漏了一些东西,要么有更好的方法来做到这一点,而且我对想法持开放态度。

在这种情况下,客户期望整数(他们希望它看起来像一个没有前导零的整数)。

此查询的结果在 Foxtrot 脚本中用于从应用程序中取消配置用户,这些数字代表我们银行系统中的分支机构。前导零会导致问题。如果结果是字符串,则将其忽略。

Aar*_*and 5

为什么首先将子字符串转换为 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
Run Code Online (Sandbox Code Playgroud)

注意:ISNUMERIC()不是一个完美的验证它是一个整数,但在这里可能没问题,因为你真的不需要int,只需要一个格式像int.

更新现在我更好地了解要求后您可以做的是转换为 int 然后再返回到字符串。由于您在 2014 年,您可以使用TRY_CONVERT()

ELSE CONVERT(varchar(12), 
  TRY_CONVERT(int, SUBSTRING(l.id, 0, charindex('-', l.id, 0)))) 
END
Run Code Online (Sandbox Code Playgroud)

您还可以考虑修复设计,以便您不必从更大的信息中解析这些重要的信息,或者至少将您的CASE表达式移动到计算列或视图中,这样您就不必将所有所有(或任何!)查询中的逻辑。