在某些情況下創建動態SQL,我得到了SQL Server 2012中(最新更新)上一個怪異的行爲試圖用自我拼接使用+ =會在某些情況下,截斷了以前的內容
@Str += ...
生成字符串時或
@Str = @Str + ...
它截斷查詢中的變量,串聯NULL值時,這是預期的行爲,除了我不是以前的內容...
這是將代碼的簡化版本降到最低,以重現我實例中的錯誤。很難重現,因爲只是將函數結果複製到臨時表(在我的情況中不可能)來修復它,所以我懷疑查詢計劃或優化。
DECLARE @CTESQL VARCHAR(MAX)= '';
SELECT
--TOP 4096--Workaround for SQL SERVER bug dropping previous text in some cases (4096 = max statement in a select clause)
@CTESQL+= CASE WHEN 1 = ROW_NUMBER() OVER (ORDER BY PvtColumnName) THEN '1'
ELSE CASE WHEN LAG(PvtColumnName) OVER (ORDER BY PvtColumnName) <> ISNULL(PvtColumnName,
ColumnName)
THEN '2'
ELSE '3'
END
END + CASE WHEN PvtColumnName IS NULL THEN '4'
ELSE (CASE WHEN 1 = ROW_NUMBER() OVER (ORDER BY t.PvtColumnName DESC)
THEN '5'
ELSE '6'
END)
END
FROM
dbo.ImportDefinition('stgPopulation') t
ORDER BY
PvtColumnName
, ColumnId
PRINT (@CTESQL);
表函數 'ImportDefinition' 還是返回了以下數據:
PvtColumnName ColumnId ColumnName
------------------- ----------- --------------------
NULL 3 Country
NULL 2 GMPSubRegion
NULL 4 ISO_Ctry
NULL 9 Source
AgeGroupCode 6 Total
AreaTypeCode 6 Total
AgeGroupCode 7 Under5
AreaTypeCode 7 Under5
AgeGroupCode 8 Urban
AreaTypeCode 8 Urban
NULL 1 RegionFullName
NULL 5 Year
預期的結果是:
343414343434363636363625
從SQL Server的實際結果是:
25
一個簡單的解決方法是使用'TOP n'修復它,但我不知道爲什麼,它很髒。
我有一些希望,強制MAXDOP 1將有所幫助,但沒有運氣。
這是第二次我遇到這個問題,所以儘管有多種解決方法,我真的很想知道發生了什麼,或者是否有一個錯誤的地方。
謝謝你的專業知識。
編輯 這裏是一個腳本,允許重現相同的行爲:
IF OBJECT_ID('dbo.MyTable', 'U') IS NOT NULL
DROP TABLE dbo.MyTable;
CREATE TABLE dbo.MyTable
(
F1 VARCHAR(255) NOT NULL
, F2 NVARCHAR(4000) NULL
)
ON [PRIMARY];
GO
INSERT INTO dbo.MyTable
(F1, F2)
VALUES
('foo', 'a')
, ('faa', 'b')
, ('fuu', 'a');
DECLARE @CTESQL VARCHAR(MAX)= '';
SELECT
@CTESQL+= CASE WHEN 1 = ROW_NUMBER() OVER (ORDER BY F2)
THEN '1'
ELSE CASE WHEN LAG(F2) OVER (ORDER BY F2) <> ISNULL(F2,
F1)
THEN '2'
ELSE '3'
END
END + CASE WHEN F2 IS NULL THEN '4'
ELSE (CASE WHEN 1 = ROW_NUMBER() OVER (ORDER BY F2 DESC)
THEN '5'
ELSE '6'
END)
END
FROM
MyTable
ORDER BY
F2;
PRINT (@CTESQL);
如果更改了基礎數據,使最後的「25」將不會發生,你得到「36」或者你得到一個空字符串或NULL ? –