我有一个开发服务器,我的T-SQL代码工作正常,但是当我将它移植到我的生产服务器时它就破坏了。这是代码:
DECLARE @ModelNumber AS int = 67787
;WITH UsedNumbers (clnum, clname1) AS
(
SELECT
clnum COLLATE SQL_Latin1_General_CP1_CI_AS AS clnum,
clname1 COLLATE SQL_Latin1_General_CP1_CI_AS AS clname1
FROM
ELITE.son_db.dbo.client
WHERE
clnum NOT LIKE '%[A-Z]%'
),
OrderedNumbers (clnum, clnum_int, clname1) AS
(
SELECT TOP 500000
clnum, CAST(clnum AS int) AS clnum_int, clname1
FROM
UsedNumbers
WHERE
CAST(clnum AS int) >= @ModelNumber
ORDER BY
clnum
)
SELECT TOP 1
REPLACE(STR(previd + 1, 6), ' ', '0') AS previd
FROM
(SELECT
clnum_int, LAG(clnum_int) OVER (ORDER BY clnum) previd
FROM
OrderedNumbers) q
WHERE
previd <> clnum_int - 1
ORDER BY
clnum_int
当我在开发服务器上运行此代码时,它会返回结果而不会出现问题。当我在生产服务器上运行它时,我收到此错误:
Msg 245,Level 16,State 1,Line 3
转换varchar值时转换失败&#39; 57235A&#39;数据类型int。
在两台服务器上,如果我将最后一个SELECT语句替换为:
SELECT *
FROM UsedNumbers
WHERE clnum LIKE '57%'
我在开发服务器或生产服务器上没有得到任何结果,所以我对错误信息感到困惑。
侧点:初始SELECT语句中的ELITE是指在两台服务器上找到的链接服务器。两个链接服务器都指向同一个数据库,即链接服务器没有指向开发和生产版本。 67787是最终用户给我的种子价值;它对程序没有意义,除了他们想要找到该数字之后的下一个数字。
有人能说出这里会发生什么吗?
答案 0 :(得分:2)
显然,在你投射
时会产生错误OrderedNumbers (clnum, clnum_int, clname1)
AS
(
SELECT TOP 500000 clnum, CAST(clnum AS int) AS clnum_int, clname1
FROM UsedNumbers
WHERE CAST(clnum AS int) >= @ModelNumber
ORDER BY clnum
)
clnum如何将VARCHAR和CAST()泄漏到int中断。生产可以并行执行cte。尝试使用ISNUMERIC(clnum)= 1
OrderedNumbers (clnum, clnum_int, clname1)
AS
(
SELECT TOP 500000 clnum, CAST(clnum AS int) AS clnum_int, clname1
FROM UsedNumbers
WHERE ISNUMERIC ( clnum ) = 1
AND CAST(clnum AS int) >= @ModelNumber
ORDER BY clnum
)
并且可能在第一个cte中使用ISNUMERIC()