SR0014:從 {Type1} 轉型為 {Type2} 時可能會發生資料遺失
RuleId |
SR0014 |
分類 |
Microsoft.Design |
中斷變更 |
中斷 |
原因
將資料行、變數或參數的資料型別隱含地轉換成另一個資料型別。
規則描述
如果將資料型別不一致地指派給資料行、變數或參數,當包含這些物件的 Transact-SQL 程式碼執行時,就會隱含地轉換這些物件。 這種類型的轉換不僅會降低效能,在某些情況下還會導致遺漏部分資料。 例如,如果必須轉換 WHERE 子句中的每一個資料行,可能會執行資料表掃描。 更糟的是,如果將 Unicode 字串轉換成使用不同字碼頁的 ASCII 字串,資料可能會遺失。
此規則不會:
檢查計算資料行的型別,因為型別須等到執行階段才知道。
分析 CASE 陳述式內的任何項目。 它也不會分析 CASE 陳述式的傳回值。
分析 ISNULL 呼叫的輸入參數或傳回值
SQL CLR 物件
若為 SQL Server Common Language Run-time (SQL CLR) 物件,會執行下列檢查:
Object 型別 |
驗證型別相容性 |
確認潛在的資料遺漏 |
---|---|---|
資料行 |
是 |
否 |
預存程序和函式參數 |
否 |
否 |
變數 |
否 |
否 |
XML 型別 |
否 |
否 |
當您將物件指派給另一個物件,且兩者都是 SQL CLR 物件型別時,它們必須是相同的型別,否則會產生警告。 您只能明確地將下列項目轉換為 SQL CLR 物件型別,否則會出現警告:binary varbinary、 char、 nchar、 varchar或 nvarchar。
系統函式
針對下列系統函式檢查傳回型別:@@ERROR、 @@FETCH_STATUS、@@IDENTITY、@@ROWCOUNT、 @@TRANCOUNT、CHECKSUM、CHECKSUM_AGG、 COUNT、COUNT_BIG、 GROUPING、STDEV、STDEVP、VAR、ARP、RANK、DENSE_RANK、NTILE、ROW_NUMBER、 CURSOR_STATUS、SYSDATETIME、SYSDATETIMEOFFSET、 SYSUTCDATETIME、DATEDIFF、DATENAME、 DATEPART、DAY、 MONTH、 YEAR、 CURRENT_TIMESTAMP、 GETDATE、GETUTCDATE、 AVG、SUM、 MIN、MAX、 DATEADD、SWITCHOFFSET、TODATETIMEOFFSET 和 ISNULL。
注意事項 |
---|
不會執行任何檢查,以確保輸入在 LEFT、 RIGHT、 CONVERT,和 CAST 函式以外的函式內容是有效的。 例如,沒有出現 SUM(datetime2 類型) 的警告,因為資料庫程式碼分析不了解 SUM 函式所預期的輸入類型。 如果輸入運算式本身有問題,會出現警告,例如如果您指定了 SUM (money + real)。 |
指定所執行的檢查
下表描述所執行的特定檢查,並且各附一個範例:
語言建構 |
檢查項目 |
範例 |
---|---|---|
參數的預設值 |
參數資料型別 |
|
CREATE INDEX 述詞 |
述詞是布林 |
|
LEFT 或 RIGHT 函式的引數 |
字串引數型別和長度 |
|
CAST 與 CONVERT 函式的引數 |
運算式和型別都有效 |
|
SET 陳述式 |
左側和右側有相容的型別 |
|
IF 陳述式述詞 |
述詞是布林 |
|
WHILE 陳述式的述詞 |
述詞是布林 |
|
INSERT 陳述式 |
值和資料行正確 |
注意事項
不會驗證萬用字元。例如:INSERT INTO t1 SELECT * FROM t2
|
SELECT WHERE 述詞 |
述詞是布林 |
|
SELECT TOP 運算式 |
運算式是整數或浮點數型別 |
|
UPDATE 陳述式 |
運算式和資料行具有相容的型別 |
|
UPDATE 述詞 |
述詞是布林 |
|
UPDATE TOP 運算式 |
運算式是整數或浮點數型別 |
|
DELETE PREDICATE |
述詞是布林 |
|
DELETE TOP 運算式 |
運算式是整數或浮點數型別 |
|
DECLARE 變數宣告 |
初始的值和資料型別可相容 |
|
EXECUTE 陳述式引數和傳回型別 |
參數和引數 |
|
RETURN 陳述式 |
RETURN 運算式具有相容的資料型別 |
|
MERGE 陳述式條件 |
條件是布林 |
|
如何修正違規
您可以指派一致的資料型別,並且視需要明確地轉換型別,以避免及解決這些問題。 如需如何明確轉換資料型別的詳細資訊,請參閱 Microsoft 網站:轉型與轉換 (Transact-SQL) (英文)。
隱藏警告的時機
您不應該隱藏這類警告。
範例
這個範例會顯示兩個將資料插入資料表中的預存程序。 第一個程序 (procWithWarning) 會造成資料型別的隱含轉換。 第二個程序 (procFixed) 示範如何加入明確的轉換以達到最佳效能,同時保留所有資料。
CREATE TABLE [dbo].[Table2]
(
[ID] INT NOT NULL IDENTITY(0, 1),
[c1] INT NOT NULL ,
[c2] INT NOT NULL ,
[c3] BIGINT NOT NULL ,
[Comment] VARCHAR (25)
)
ON [PRIMARY]
CREATE PROCEDURE [dbo].[procWithWarning]
(
@Value1 INT,
@Value2 INT,
@Value3 BIGINT,
@Comment CHAR(30)
)
AS
BEGIN
INSERT INTO [Table2] ([c1], [c2], [c3], Comment)
VALUES (@Value1, @Value2, @Value3, @Comment)
END
CREATE PROCEDURE [dbo].[procFixed]
(
@Value1 INT,
@Value2 INT,
@Value3 BIGINT,
@Comment CHAR(10)
)
AS
BEGIN
INSERT INTO [Table2] ([c1], [c2], [c3], Comment)
VALUES (@Value1, @Value2, @Value3, CAST(@Comment AS VARCHAR(25)))
END