【问题标题】:Why do I get "String or binary data would be truncated" in some cases only?为什么仅在某些情况下会出现“字符串或二进制数据将被截断”?
【发布时间】:2011-06-28 10:03:26
【问题描述】:

我仅在某些情况下解决 SQL Server 错误消息 8152“字符串或二进制数据将被截断”的问题。 以下查询与那个类似,即抛出错误。

CREATE TABLE SourceValues (
    SourceId INT IDENTITY (1,1),
    SourceValue VARCHAR(3)
)
GO
INSERT INTO SourceValues (SourceValue) VALUES ('aaa')
INSERT INTO SourceValues (SourceValue) VALUES ('aab')
INSERT INTO SourceValues (SourceValue) VALUES ('aa')
INSERT INTO SourceValues (SourceValue) VALUES ('ab')
INSERT INTO SourceValues (SourceValue) VALUES ('a')
INSERT INTO SourceValues (SourceValue) VALUES ('b')
GO

PRINT 'NOT WORKING #1'
CREATE TABLE TargetValues (TargetValue VARCHAR(2))
INSERT INTO TargetValues (TargetValue) 
SELECT s1.SourceValue
FROM SourceValues s1, SourceValues s2
WHERE s1.SourceId=s2.SourceId+1 AND s1.SourceValue!='aab'
DROP TABLE TargetValues
GO

PRINT 'NOT WORKING #2'
CREATE TABLE TargetValues (TargetValue VARCHAR(2))
INSERT INTO TargetValues (TargetValue) 
SELECT s1.SourceValue
FROM SourceValues s1, SourceValues s2
WHERE s1.SourceId=s2.SourceId+1 AND s1.SourceValue!='aab'
ORDER BY s1.SourceValue
DROP TABLE TargetValues
GO

PRINT 'WORKING #1'
CREATE TABLE TargetValues (TargetValue VARCHAR(2))
INSERT INTO TargetValues (TargetValue) 
SELECT s1.SourceValue
FROM SourceValues s1, SourceValues s2
WHERE s1.SourceId=s2.SourceId+1 AND s1.SourceValue!='aab'
ORDER BY s2.SourceValue -- <-- using s2 instead of s1 for order
DROP TABLE TargetValues
GO

PRINT 'WORKING #2'
CREATE TABLE TargetValues (TargetId INT IDENTITY (1,1),TargetValue VARCHAR(2)) -- <-- using identity column
INSERT INTO TargetValues (TargetValue) 
SELECT s1.SourceValue 
FROM SourceValues s1, SourceValues s2 
WHERE s1.SourceId=s2.SourceId+1 AND s1.SourceValue!='aab'
DROP TABLE TargetValues
GO

DROP TABLE SourceValues

问题出现在查询“NOT WORKING 1”中,其他问题是关于解决方案的一些想法。 有谁知道不工作查询和工作查询之间的区别?

我在 SQL Server 2005、SQL Server 2008 和 SQL Server 2008 R2 上对此进行了测试,得到了相同的结果。但我听说在另一个 SQL Server 2008 R2 实例上的所有查询都失败了。

还请注意,我已经通过将 TargetValues 表中的 varchar 设置为 3 的大小(更正了错误)解决了这个问题。

【问题讨论】:

    标签: sql-server


    【解决方案1】:

    这是当数据溢出字段长度时,例如abc进入char(2)

    您的源数据中有aaa

    无法关闭或静默截断

    查看SQL Server silently truncates varchar's in stored procedures 了解您可能想知道的更多信息

    编辑:

    这是奇怪的行为

    这仍然会因显式 JOIN 失败并中断“工作”查询之一

    选择 s1.SourceValue 从 SourceValues s1 加入 SourceValues s2 在 s1.SourceId=s2.SourceId+1 WHERE s1.SourceValue'aab' 按 s2.SourceValue,s1.SourceValue 排序

    我在 MS Connect 上找不到任何关于此的信息

    【讨论】:

    • 我认为如果你 SET ANSI_WARNINGS OFF,它会默默地允许插入和截断值
    • @AdaTheDev: 是的,但是您破坏了索引视图、链接服务器等。从长远来看,这不是一个可支持的选项
    • 是的,同意。澄清一下,我不建议将其关闭 :)
    • 抱歉,我知道问题出在哪里。我想知道为什么会出现错误,因为我只插入了 2 个字符的数据(aaa 被 join 消除,aab 被 where 条件消除)
    • @woni:我现在看到并且可以在 SQL Server 2008 和 SQL Server 2005 上重现。好问题。
    【解决方案2】:

    如果我是对的,您可以尝试将 'aaa' 添加到 varchar(2) 字段。这是不可能的,因为数据会被截断。

    【讨论】:

    • 不,没有插入aaa。被join消除。
    【解决方案3】:

    SQL 服务器知道架构是不同的。尽管有 where 子句,您仍然最终将 VARCHAR(3) 列选择到 VARCHAR(2) 接收列中。将结果选择转换/转换为 varchar(2),它将起作用。将生成的类型像这样链接到 where 子句可能不是最佳实践 - where 子句可能会在稍后的某个日期返回一个 3 个字母的列(当然取决于您的数据)并且它会破坏它,但是一个显式的 CAST选择中的 /CONVERT 将解决此特定问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-21
      • 2022-01-11
      相关资源
      最近更新 更多