【问题标题】:Why does SQL MERGE statement produce either truncation error or overflow error?为什么 SQL MERGE 语句会产生截断错误或溢出错误?
【发布时间】:2017-03-23 23:40:42
【问题描述】:

想象一下下面的 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 表最初设计用于将源的 VENDOR_KEY(一个 varchar)始终转换为 int,然后再通过数据。现在这是不可持续的,因为 VENDOR_KEY 的 varchar 溢出了 VendorIDInt 列

消息 248,级别 16,状态 1,行 524
varchar 值 '89617719042' 的转换溢出了一个 int 列。

第一次尝试,我尝试将 VendorIDInt 列类型更改为 bigint,然后将 VENDOR_KEY 转换为 bigint。这不起作用,因为显示错误

消息 8152,级别 16,状态 14,行 524
字符串或二进制数据将被截断。声明已终止。

第二次尝试,我更改了 tblVendor 以添加 VendorID varchar 类型列,同时注释掉上述合并语句中涉及强制转换和 VendorIDInt 的行。我的想法是,当我可以将数据带到新的 varchar VendorID 列时,为什么还要使用 VendorIDInt 列?这也没有用

消息 8152,级别 16,状态 14,行 524
字符串或二进制数据将被截断。该语句已终止。

我收到了同样的错误。

第三次尝试,我没有想法,只是按原样运行上面的合并语句,没有任何注释试图提取 VendorIDInt 和 VendorID 列留在其中的数据。再一次,同样的截断错误。那里并不奇怪。

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

最终目标是从源表中获取数据到我的表中,要么出现 int 列溢出错误,要么出现截断错误。我陷入了一个看似不可能的境地。

还有哪些前进的道路?谢谢。

【问题讨论】:

  • SYN_VENDOR_A 表上是否有触发器?
  • 您显示了tblVendor 的架构,但没有显示SYN_VENDOR 的架构
  • 我不知道该同义词表上有任何触发器。
  • 如果您使用的是 SQL Server 2012,请尝试在合并条件中添加另一个过滤器,例如 AND TRY_CONVERT(INT, SOURCE.VENDOR_KEY) IS NOT NULL

标签: sql sql-server tsql


【解决方案1】:

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

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

LEFT(VENDOR_NAME, 50)

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-06
    • 1970-01-01
    • 2019-11-15
    • 2021-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多