SQL Server真的对每个';然后';格表达式中的子句?
我正在使用一个遗留系统中的ItemNumber字段,该字段中99%是数字,但也有一些记录包含字母。这些数字都用前导零填充,所以我想我可以将它们转换为bigint来解决这个问题,但是当它到达包含字母的记录时,当然会抛出一个错误 我原以为下面的case语句会起作用,但它仍然抛出了错误。如果isnumeric(itemnumber)=1条件不正确,SQL Server为什么要评估强制转换SQL Server真的对每个';然后';格表达式中的子句?,sql,sql-server,Sql,Sql Server,我正在使用一个遗留系统中的ItemNumber字段,该字段中99%是数字,但也有一些记录包含字母。这些数字都用前导零填充,所以我想我可以将它们转换为bigint来解决这个问题,但是当它到达包含字母的记录时,当然会抛出一个错误 我原以为下面的case语句会起作用,但它仍然抛出了错误。如果isnumeric(itemnumber)=1条件不正确,SQL Server为什么要评估强制转换 select case when isnumeric(itemnumber) = 1 th
select case when isnumeric(itemnumber) = 1
then cast(itemnumber as bigint)
else itemnumber
end ItemNumber
from items
最好的解决方法是什么?可能是因为:
对于某些非数字字符,例如加号(+)、减号(-)和有效的货币符号,例如美元符号($),ISNUMERIC返回1。有关货币符号的完整列表,请参见货币和小额货币(Transact-SQL)
表达式尝试将
VARCHAR
值转换为BIGINT
值(如果它是数字),如果不是,则保持该值不变
由于在CASE
语句中混合了数据类型,SQL Server
尝试将它们全部转换为BIGINT
,但在非数值上失败
如果您只想省略非数值,请去掉ELSE
子句:
SELECT CASE ISNUMERIC(itemnumber)
WHEN 1 THEN
CAST(itemnumber AS BIGINT)
END
FROM items
问题是您仍然在混合您的类型:
select case when isnumeric(itemnumber) = 1
then cast(itemnumber as bigint) --bigint
else itemnumber --varchar or whatever
end ItemNumber --????
from items
你需要两列
select case when isnumeric(itemnumber) = 1
then cast(itemnumber as bigint) --bigint
else -1
end NumericItemNumber
from items
select case when isnumeric(itemnumber) = 1
then ''
else itemnumber
end StringItemNumber
from items
然后,您需要构建一个同时接受int和varchar的查询请与我们共享错误消息好吗?@Quassnoi Msg 8114,16级,状态5,第2行将数据类型varchar转换为bigint时出错。因为
案例
的结果必须是一个类型。应该是什么类型的?你有一个bigint
和一个varchar
。你想做什么?请发布一些样本数据和所需的信息output@ta.speot.is谢谢我添加了另一个cast以将其转换回varchar,现在它工作得很好。这可能是相关的:从result\u表达式中的类型集和可选的else\u result\u表达式中返回优先级最高的类型。有关更多信息,请参见数据类型PrevenceThance。问题不在于它给出了边缘情况的假阳性,尽管只有少数记录是非数字的,它们只包含a-z+1的字母。这个人知道如何使用SQL Server。值得一提的是,这里可以学习确定CASE
表达式的返回类型的规则:从result_表达式和可选的else_result_表达式的类型集中返回优先级最高的类型。有关详细信息,请参阅数据类型Prevence。我通过将bigint转换回varchar来解决此问题。@BrandonMoore:这将首先将数值转换成int,然后再转换回varchar,并保持非数值不变。案例的目的是什么首先,您想用它解决什么问题?你刚才是不是想去掉什么的前导零?@Quassnoi是的,我只是想去掉前导零。我正在准备从旧系统导入到新系统中的数据,但是如果字段太长,新系统会截断字段的结尾,所以我只需要删除前导零,这样就不会发生这种情况。@BrandonMoore:那好吧。