2016-11-17 148 views
-1

我尝试在表中的一个字段中将字符串值转换为int,但仅在该值存储可以转换为int的值的情况下(在另一种情况下,必须返回原始值)。例如:SQL Server 2014:只有在值可以被转换的情况下如何将字符串值转换为int值?

DECLARE @ErrorCode nvarchar(1024) 
    SET @ErrorCode = 'a10' 
    SELECT IIF(TRY_CAST(@ErrorCode AS int) IS NULL, @ErrorCode, CAST(@ErrorCode AS int)) 

我在StackOverflow上看到过类似的代码。

我的问题是,SQL Server(2014)似乎没有短路,并且始终执行转换,即使TRY_CAST(@ErrorCode AS int)结果为NULL。上面的代码的结果是错误“将nvarchar值'a10'转换为数据类型int时转换失败。”

this sample on rextester.com

我也试过其它变体,相同的结果:

SELECT CASE WHEN TRY_CAST(@ErrorCode AS int) IS NULL THEN @ErrorCode ELSE (SELECT CAST(@ErrorCode AS int)) END 
SELECT CASE TRY_CAST(@ErrorCode AS int) WHEN 1 THEN CAST(@ErrorCode AS int) ELSE @ErrorCode END 

我怎样才能实现我的目标(避免情况下@ErrorCode值不能被铸造铸)?

+0

你可以用'ISNUMERIC()'函数检查是否可以解析字符串 – Petaflop

+0

显示一些示例数据。我在这里看到的问题是,一列只能有1种类型。所以想要返回一个int,如果它是一个int或另一个类型在同一列不会工作。你打算如何处理这个问题? – Tanner

+0

我不是MS SQL Server的专家,但是我会检查这个值是否与正则表达式相同,如果它只包含数字,然后它被转换为int。 –

回答

1

一个简单的解决办法是使用COALSECE

DECLARE @ErrorCode nvarchar(1024) 
SET @ErrorCode = 'a10' 
SELECT COALSECE(CAST(TRY_CAST(@ErrorCode AS int) as nvarchar(1024)), @ErrorCode) 

不过,我看不出铸造成int,然后返回到nvarchar的点。

+0

问题是我必须将'0000'等值转换为'0',以便以后能够查询'0'。由于实施的解决方案使用规则引擎,因此查询时无法投射值。我需要一个值,我可以检查。我编辑了问题中的代码,将int值转换回nvarchar以获得相同的类型。 –

+0

我明白了。但值得一提的是,如果值是'000a',它仍然是'000a'。如果你想修剪前导零,即使对于非数值,你也必须以不同的方式来完成。 –

+0

是的。但在这种情况下,我不需要修剪前导零。这只适用于表格中可以存在的数字。 –

1

要验证NULL你应该IS NULL

DECLARE @ErrorCode NVARCHAR(1024) 

SET @ErrorCode = 'a10' 

SELECT IIF(TRY_CAST(@ErrorCode AS int) IS NULL, @ErrorCode, CAST(CAST(@ErrorCode AS int) AS VARCHAR(50))) 

您需要的INT再次再次转换为VARCHAR避免隐式转换。 IIF从true_value和false_value类型中返回具有最高优先级的数据类型。

+0

Ups。我在查询中犯了一个错误。你的答案有效。不知道为什么它是downvoted。 –

0

我看到的问题是试图在一个列中保存2种不同的类型。我不确定您计划如何使用此信息,但可以根据类型将值分为数字和文本列。你可以做一个ISNUMERIC()检查和CASTINT如果这是真的,否则把它作为文本,像这样:

CREATE TABLE #ErrorCodes (ErrorCode NVARCHAR(10)) 

INSERT INTO #ErrorCodes 
     (ErrorCode) 
VALUES ('123'), 
     ('a10'), 
     ('bbb'), 
     ('456') 

SELECT ErrorCode AS OriginalVal , 
     CASE WHEN ISNUMERIC(ErrorCode) = 1 THEN CAST(ErrorCode AS INT) 
      ELSE NULL 
     END AS NumericVal , 
     CASE WHEN ISNUMERIC(ErrorCode) = 0 THEN ErrorCode 
      ELSE NULL 
     END AS NonNumericVal 
FROM #ErrorCodes 

DROP TABLE #ErrorCodes 

产地:

OriginalVal NumericVal NonNumericVal 
===================================== 
123   123   NULL 
a10   NULL  a10 
bbb   NULL  bbb 
456   456   NULL