此代码在直接传递值时会引发错误,但如果使用参数传递值则不会显示任何错误。
- 它会抛出错误
DECLARE @sql NVARCHAR(4000)
DECLARE @ID INT=1234
SET @sql = N'select
[count]
FROM dbo.Table_1 AS t
JOIN dbo.table_2 AS t2 ON t.store_number = t2.store_number
AND t2.[year] = 17
AND t2.week_of_year = 6
AND t2.day_of_week = 2
WHERE t.RC_ID = @ID'
EXEC sp_executesql @sql
- 它会抛出错误
select
[count]
FROM dbo.Table_1 AS t
JOIN dbo.table_2 AS t2 ON t.store_number = t2.store_number
AND t2.[year] = 17
AND t2.week_of_year = 6
AND t2.day_of_week = 2
WHERE t.ID = 1234
-- IT WORKS
DECLARE @sql
DECLARE @ID INT
SET @ID = 1234
select
[count]
FROM dbo.Table_1 AS t
JOIN dbo.table_2 AS t2 ON t.store_number = t2.store_number
AND t2.[year] = 17
AND t2.week_of_year = 6
AND t2.day_of_week = 2
WHERE t.ID = @ID
错误是:
Msg 245,Level 16,State 1,Line 1转换时转换失败 varchar值' TEST'数据类型int。
但是没有像'测试'在表中。
答案 0 :(得分:0)
您作为整数进行比较的一个值包含错误的值:
select t2.*
from table_2 t2
where try_convert(int, year) is null or try_convert(int, week_of_year) is null or
try_convert(int, day_of_week) or try_convert(int, id) is null;
是否发生错误取决于执行计划。
答案 1 :(得分:0)
您要过滤的某个表列不是数字数据类型。当你这样做
WHERE VarcharColumn = 1
SQL Server引擎将始终尝试将最复杂的类型转换为最简单的类型,在这种情况下,“1”是一个整数,VarcharColumn是VARCHAR
,因此引擎将尝试转换存储的所有值在按值1过滤之前,在VarcharColumn中为整数。由于存储的至少一个值不是整数(“TEST”),因此转换失败并弹出该消息。
你有2个解决方案:
WHERE Column = '1'
当然,请务必检查数据类型。
同样在您的dynamicSQL查询中,@ID
的声明必须在您的脚本中(它也缺少初始值)。
DECLARE @sql NVARCHAR(4000)
SET @sql = N'
DECLARE @ID INT = 1
select
[count]
FROM dbo.Table_1 AS t
JOIN dbo.table_2 AS t2 ON t.store_number = t2.store_number
AND t2.[year] = 17
AND t2.week_of_year = 6
AND t2.day_of_week = 2
WHERE t.RC_ID = @ID'
EXEC sp_executesql @sql
错误弹出“有时”的原因是因为语句的不同形式使执行计划以不同的顺序执行。如果它首先尝试将varchar值转换为int,则它将失败。如果它试图将int值转换为varchar(例如),则它不会失败。
要找到问题,请尝试以下方法:
SELECT
*
FROM
dbo.Table_1 AS T
WHERE
CONVERT(VARCHAR(200), T.store_number) = 'Test' OR
CONVERT(VARCHAR(200), T.ID) = 'Test'
SELECT
*
FROM
dbo.table_2 AS T
WHERE
CONVERT(VARCHAR(200), T.store_number) = 'Test' OR
CONVERT(VARCHAR(200), T.[year]) = 'Test' OR
CONVERT(VARCHAR(200), T.week_of_year) = 'Test' OR
CONVERT(VARCHAR(200), T.day_of_week) = 'Test'
答案 2 :(得分:0)
从我看到你试图在sp_executeSQL中使用参数(@id)而不传递它。快速修复就是做那样的事情
DECLARE @sql NVARCHAR(4000)
DECLARE @ID INT = 10
SET @sql = N'select
[count]
FROM dbo.Table_1 AS t
JOIN dbo.table_2 AS t2 ON t.store_number = t2.store_number
AND t2.[year] = 17
AND t2.week_of_year = 6
AND t2.day_of_week = 2
WHERE t.RC_ID = ' + cast(@ID as nvarchar(20))
EXEC sp_executesql @sql
希望这有帮助