18

我有这张桌子:

CREATE TABLE Vendors

(
    VendorID            NUMERIC(10)     NOT NULL,
    VendorName          CHAR(50)        NOT NULL,
    VendorAddress       VARCHAR(30)     NULL,
    VendorCityName      VARCHAR(20)     NOT NULL,
    VendorStateName     CHAR(2)         NOT NULL,
    VendorZip           VARCHAR(10)     NULL,
    VendorContactName   CHAR(50)        NOT NULL,
    VendorContactPhone  VARCHAR(12)     NOT NULL,
    VendorContactEmail  VARCHAR(20)     NOT NULL,
    VendorSpecialty     CHAR(20)        NOT NULL

    CONSTRAINT VendorsPK        PRIMARY KEY (VendorID)      
);

而这个插入:

INSERT INTO Vendors(VendorID, VendorName, VendorAddress, 
  VendorCityName, VendorStateName, VendorZip, VendorContactName, 
  VendorContactPhone, VendorContactEmail, VendorSpecialty)
VALUES(151330, 'Hyperion', '77 West 66th Street', 'New York', 
  'NY', 10023, 'John Hinks', '212-337-6564', 
  'jhinks@hyperionbooks.com', 'Popular fiction')

为什么这个语句会产生 8152 错误?

4

3 回答 3

34

VendorContactEmail只有 20 个字节。第一行 ( ) 上的电子邮件地址jhinks@hyperionbooks.com比这更长 - 24 个字节。而且许多电子邮件地址会更长。谁决定在电子邮件地址栏中只允许 20 个字符?根据标准,这应该是VARCHAR(320)- 64 个字符<localpart>+ 1 @+ 255 个<domain>.

至于错误信息本身,今天比当时更容易找到罪魁祸首。

于 2013-04-23T14:45:30.890 回答
11

如何强制导致截断的操作仍然执行

  • 你知道什么是截断吗?
  • 你知道什么会被截断吗?
  • 您是否打算截断长数据以适应?

当且仅当您对上述问题回答“是”时,您可以强制插入忽略警告并运行。如果您对以上任何一项的回答为否,请继续阅读。

SET ANSI_WARNINGS  OFF;
-- Your operation TSQL here.
SET ANSI_WARNINGS ON;

(资源)

在这种情况下截断是什么

截断只是将尽可能多的值放入列中,然后丢弃任何不适合的部分。例如,将The quick brown fox jumps over the lazy dog截断为 13 个字符将是The quick bro

为什么我会收到此错误消息

当您尝试插入不适合目标列定义的数据时,您会收到此错误,因为数据太短。

我正在尝试插入多行数据并想确定哪些行不适合

Aaron 的出色回答指出,如果您运行的是 SQL Server 2019 或更高版本,您实际上会收到一条消息,其中包含不适合的列和值 - 这太棒了!但是,如果您运行的不是新版本,请继续阅读以获取提示。

如果您在尝试批量插入多行数据时收到此错误消息,您可以尝试将插入拆分为多个插入并分别运行它们以缩小 long 值的位置。

或者,您可以将数据插入到一个新的临时表中,并在该临时表中搜索不适合您的目标表的值。

--(insert into new temp table #Vendors)
INSERT INTO #Vendors(VendorID, VendorName, VendorAddress, 
  VendorCityName, VendorStateName, VendorZip, VendorContactName, 
  VendorContactPhone, VendorContactEmail, VendorSpecialty)
VALUES(151330, 'Hyperion', '77 West 66th Street', 'New York', 
  'NY', 10023, 'John Hinks', '212-337-6564', 
  'jhinks@hyperionbooks.com', 'Popular fiction')

然后查询不适合的行。

--(query for values that don't fit)
SELECT *,
LEN(VendorContactEmail) AS Length
FROM #Vendors
WHERE LEN(VendorContactEmail) > 20 --set your destination column length is here

有关空白处理和二进制数据长度的信息,另请参阅LENDATALENGTH文档。

于 2017-02-09T17:39:13.513 回答
1

您还可以使用以下表达式最小化列值的长度:

LEFT(columnName, 250) + '...'  

我试过了,它有效。

于 2019-12-26T06:17:44.957 回答