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 脚本中用于从应用程序中取消配置用户,这些数字代表我们银行系统中的分支机构。前导零会导致问题。如果结果是字符串,则将其忽略。
为什么首先将子字符串转换为 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
表达式移动到计算列或视图中,这样您就不必将所有所有(或任何!)查询中的逻辑。