昨天突然出現一個報告,有人因為問題Msg 2628, Level 16, State 1, Line 57 String or binary data would be truncated in table 'tempdb.dbo.#BC6D141E', column 'string_2'. Truncated value: '!012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678'.出現而無法再獲取一些資料。
沒有我們的表格,我無法創建復制品。這是我能到達的最接近的:
-- Create temporary table for results
DECLARE @results TABLE (
string_1 nvarchar(100) NOT NULL,
string_2 nvarchar(100) NOT NULL
);
CREATE TABLE #table (
T_ID BIGINT NULL,
T_STRING NVARCHAR(1000) NOT NULL
);
INSERT INTO #table VALUES
(NULL, '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789'),
(NULL, '!0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789!');
WITH abc AS
(
SELECT
'' AS STRING_1,
t.T_STRING AS STRING_2
FROM
UT
INNER JOIN UTT ON UTT.UT_ID = UT.UT_ID
INNER JOIN MV ON MV.UTT_ID = UTT.UTT_ID
INNER JOIN OT ON OT.OT_ID = MV.OT_ID
INNER JOIN #table AS T ON T.T_ID = OT.T_ID -- this will never get hit because T_ID of #table is NULL
)
INSERT INTO @results
SELECT STRING_1, STRING_2 FROM abc
ORDER BY LEN(STRING_2) DESC
DROP TABLE #table;
正如您所看到的,join#table不能產生任何結果,因為所有的結果T_ID都是NULL我得到上面提到的錯誤。結果集為空。
如果結果集中包含超過 100 個字符的文本,那將是可以的,但情況并非如此,因為它是空的。如果我洗掉INSERT INTO @results并顯示結果,它不包含任何超過 100 個字符的文本。ORDER BY僅用于確定錯誤的文本值(使用原始資料)。
當我使用SELECT STRING_1, LEFT(STRING_2, 100) FROM abc它時,它確實有效,但它不包含要被截斷的文本。
因此:我錯過了什么?它是 SQL Server 的錯誤嗎?
uj5u.com熱心網友回復:
-- this will never get hit是一個不好的假設。眾所周知并記錄在案,SQL Server 可能會在結果明顯不可能之前嘗試評估您的部分查詢。
一個更簡單的復制(來自
這表明 SQL Server 期望在過濾器消除較長的值之前轉換所有值。t1并且很難預測或控制 SQL Server 何時以您不期望的順序處理您的查詢 - 您可以嘗試使用查詢提示嘗試強制排序或遠離哈希連接,但這些可能會導致其他更多以后出現嚴重問題。
最好的解決方法是調整臨時表的大小以匹配源(換句話說,使其足夠大以適應源中的任何值)。博客文章和db<>fiddle解釋了解決此問題的其他一些方法,但宣告列足夠寬是最簡單且干擾最小的方法。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/415822.html
標籤:
