为什么SQL MERGE语句会产生截断错误或溢出错误?

时间:2017-03-21 15:43:16

标签: sql sql-server tsql

想象一下以下tblVendor表:

SourceSystemID (FK, tinyint, not null)
VendorIDInt (int, null)
VendorID (varchar(255), not null)
VendorName (varchar(50), null)

这是一个尝试将SOURCE TABLE与我的tblVendor表合并的块(使用tblSourceSystem表):

MERGE tblVendor as TARGET
USING SYN_VENDOR_A as SOURCE
    ON TARGET.SourceSystemID = CAST(ISNULL((select SourceID from tblSourceSystem where SourceCode like SOURCE_SYSTEM), 0) as tinyint)
        AND TARGET.VendorID = SOURCE.VENDOR_KEY

WHEN MATCHED AND (SOURCE_SYSTEM = 'REG') THEN
    UPDATE
    SET
        SourceSystemID  = CAST(ISNULL((select SourceID from tblSourceSystem where SourceCode like SOURCE_SYSTEM), 0) as tinyint),
        VendorIDInt     = CAST(VENDOR_KEY as int),
        VendorID        = VENDOR_KEY,
        VendorName      = VENDOR_NAME

WHEN NOT MATCHED AND (SOURCE_SYSTEM = 'REG') THEN
    INSERT (
        SourceSystemID,
        VendorIDInt,
        VendorID,
        VendorName
    )
    VALUES (
        (SELECT CAST(ISNULL(SourceID, 0) as tinyint) from tblSourceSystem where SourceCode like SOURCE_SYSTEM), --varchar
        CAST(VENDOR_KEY as int), --varchar attemping to convert to an int
        VENDOR_KEY, --varchar
        VENDOR_NAME --varchar
    );

tblVendor表最初设计用于SOURCE的VENDOR_KEY(varchar)在数据传输之前始终转换为int的位置。现在这是不可持续的,因为VENDOR_KEY的varchar溢出了VendorIDInt列

  

Msg 248,Level 16,State 1,Line 524   
varchar值'89617719042'的转换溢出了一个int列。

首先尝试,我尝试将VendorIDInt列类型更改为bigint,然后将VENDOR_KEY转换为bigint。这不起作为错误显示

  

Msg 8152,Level 16,State 14,Line 524   
字符串或二进制数据将被截断。声明已经终止。

第二次尝试,我修改了tblVendor以添加VendorID varchar类型列,同时注释掉上面涉及cast和VendorIDInt的merge语句中的行。我的想法是,当我可以将数据传递到新的varchar VendorID列时,为什么甚至使用VendorIDInt列?这也行不通

  

Msg 8152,Level 16,State 14,Line 524   
字符串或二进制数据将被截断。该语句已终止。

我收到了同样的错误。

第三次尝试,我没有想法,只是简单地运行上面的合并语句,没有注释试图提取数据同时留下VendorIDInt和VendorID列。再次,同样的截断错误。这并不奇怪。

为什么同样的截断错误反复出现?

最终目标是从源表中获取数据到我的表,并显示int列溢出错误或显示截断错误。我陷入了似乎不可能的局面。

还有其他前进道路吗?谢谢。

1 个答案:

答案 0 :(得分:1)

出现截断错误的原因是因为同义词表的VENDOR_NAME列包含超过50个字符的记录。

使用以下内容后错误消失了:

LEFT(VENDOR_NAME, 50)

我用来解决问题的方法是通过注释并逐个隔离每一列并重复运行MERGE。

我知道这是一种蛮力方法。如果有人遇到这样的问题,请随意发布更有效的策略。