我正在观察一种奇怪的行为。以下与将nvarchar
的子字符串转换为tinyint
相关的代码运行正常:
DECLARE @s nvarchar(50) = N'Line 1'
DECLARE @n tinyint = SUBSTRING(@s, 6, 10)
SELECT
N'Line 1' AS explicit_nvarchar,
@s AS nvarchar_variable,
SUBSTRING(@s, 6, 10) AS nvarchar_substring
, @n AS tinyint_var_converted_earlier
, CAST(SUBSTRING(@s, 6, 10) AS tinyint) AS cast_sub_var
, CAST(SUBSTRING(N'Line 1', 6, 10) AS tinyint) AS cast_nvarchar_substr
我可以在Microsoft SQL Server Management Studio中观察以下输出:
。
但是,如果注释行被取消注释,那么尝试使用表中的SELECT
的代码将失败:
Select
[order].[identifier] As [order_identifier],
[plan_data].[starts_on] As [from],
[plan_data].[ends_on] As [to],
[workplace].[identifier] AS line_identifier,
SUBSTRING([workplace].[identifier], 6, 10) AS line_no_str
--, CAST(SUBSTRING([workplace].[identifier], 6, 10) AS int) AS line_no
From
...
用评论线...
但使用未注释的行(转换为tinyint
或int
)...
更新:奇怪。我已将最后一行添加到WHERE以检查是否所有行
包含'Line...
Where
[plan].[identifier] = @lPlanIdentifier And
(
[plan_data].[starts_on] Between @fromUTC And @toUTC Or
[plan_data].[ends_on] Between @fromUTC And @toUTC)
AND LEFT([workplace].[identifier], 4) = N'Line'
......突然间它也与未注释的线一起工作。我怎样才能发现导致问题的原因?
更新2:我应该完全按照发布时的Hamlet Hakobyan's answer进行操作。当看到桌子内部时,我可以看到:
答案 0 :(得分:4)
identifier
列中有SUBSTRING([workplace].[identifier], 6, 10)
返回ined
的值。
尝试此查询:
SELECT * FROM [workplace]
WHERE SUBSTRING([identifier], 6, 10) = N'ined'
答案 1 :(得分:1)
如评论和其他答案所示,对于未能投放到[workplace].[identifier]
的一行或多行,您在INT
中有一个值。将以下内容添加到WHERE
子句时,在SELECT
子句中转换之前删除了包含此数据的行:
LEFT([workplace].[identifier], 4) = N'Line'
运行以下内容以获取[workplace].[identifier]
SELECT DISTINCT [workplace].[identifier]
FROM [workplace]
答案 2 :(得分:1)
每当您将varchar转换为数字时,找到数据的最简单方法是使用IsNumeric
。但IsNumeric
并不代表IsInteger
,因此G Mastros
SELECT
[order].[identifier] As [order_identifier],
[plan_data].[starts_on] As [from],
[plan_data].[ends_on] As [to],
[workplace].[identifier] AS line_identifier,
SUBSTRING([workplace].[identifier], 6, 10) AS line_no_str
--, CAST(SUBSTRING([workplace].[identifier], 6, 10) AS int) AS line_no
FROM
...
WHERE
IsNumeric(SUBSTRING([workplace].[identifier], 6, 10) + '.0e0') = 0
如果您无法修复它,但是您可以使用默认值,那么只有在合法的情况下才能使用case语句进行转换。
SELECT
[order].[identifier] As [order_identifier],
[plan_data].[starts_on] As [from],
[plan_data].[ends_on] As [to],
[workplace].[identifier] AS line_identifier,
CASE WHEN IsNumeric(SUBSTRING([workplace].[identifier], 6, 10) + '.0e0') = 1
THEN CAST(SUBSTRING([workplace].[identifier], 6, 10) AS int)
ELSE Null --Default to null in this example
END as line_no