查询在不同服务器上的工作方式

时间:2017-12-05 21:31:30

标签: sql-server tsql

我有一个开发服务器,我的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是最终用户给我的种子价值;它对程序没有意义,除了他们想要找到该数字之后的下一个数字。

有人能说出这里会发生什么吗?

1 个答案:

答案 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()