SR0014: {Type1} から {Type2} にキャストするとデータ損失が発生する可能性があります。

規則 ID

SR0014

分類

Microsoft.Design

互換性に影響する変更点

なし

原因

列、変数、またはパラメーターに対するデータ型が暗黙的に別のデータ型に変換されます。

規則の説明

列、変数、またはパラメーターに割り当てられるデータ型が一貫していない場合、それらのオブジェクトを含む Transact-SQL コードが実行されるときにそれらが暗黙的に変換されます。 このような変換処理は、パフォーマンスを下げるだけでなく、場合によっては、微量なデータ損失を引き起こすことがあります。 たとえば、WHERE 句の中のすべての列を変換する必要がある場合、テーブル スキャンが実行される可能性があります。 さらに悪いことに、Unicode 文字列が異なるコード ページを使用する ASCII 文字列に変換される場合、データが失われる可能性があります。

この規則では次の処理は行いません。

  • 計算列の型のチェック。これは、実行時まで型がわからないためです。

  • CASE ステートメント内のすべての項目の分析。 CASE ステートメントの戻り値の分析も行いません。

  • 呼び出しの入力パラメーターまたは戻り値が ISNULL であるかどうかの分析。

SQL CLR オブジェクト

SQL Server 共通言語ランタイム (SQL CLR) オブジェクトについては、次のチェックが実行されます。

オブジェクト型

型の互換性の検査

データ損失の可能性の検査

ストアド プロシージャと関数パラメーター

変数

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 PROCEDURE p1(
@p1 INT = 1)
AS
BEGIN
END

CREATE INDEX 述語

述語がブール型であること

CREATE INDEX index1 ON table1 (column1) 
WHERE column1 > 10

LEFT 関数または RIGHT 関数の引数

文字列の引数型と長さ

SET @v = LEFT('abc', 2)

CAST 関数と CONVERT 関数の引数

式と型が有効であること

SET @v = CAST('abc' AS CHAR(10))

SET ステートメント

左辺と右辺の型に互換性があること

SET @v1 = 'xyz'
SELECT @v1 = c1 FROM t1

IF ステートメント述語

述語がブール型であること

IF (@v > 10)

WHILE ステートメント述語

述語がブール型であること

WHILE (@v > 10)

INSERT ステートメント

値と列が正しいこと

INSERT INTO t1(c1, c2) VALUES (99, 'xyz')
INSERT INTO t1 SELECT c1 FROM t2.
メモメモ
ワイルドカードは検証されません。例: INSERT INTO t1 SELECT * FROM t2

SELECT WHERE 述語

述語がブール型であること

SELECT * FROM t1 WHERE c1 > 10

SELECT TOP 式

式が Integer 型または Float 型であること

SELECT TOP 4 * FROM t1 
SELECT TOP 1.5 PERCENT * FROM t1

UPDATE ステートメント

式と列の型に互換性があること

UPDATE t1 SET c1 = 100

UPDATE 述語

述語がブール型であること

UPDATE t1 SET c1 = 100 
WHERE c1 > 100

UPDATE TOP 式

式が Integer 型または Float 型であること

UPDATE TOP 4 table1

DELETE 述語

述語がブール型であること

DELETE t1 WHERE c1 > 10

DELETE TOP 式

式が Integer 型または Float 型であること

DELETE TOP 2 FROM t1

DECLARE 変数宣言

初期値とデータ型に互換性があること

DECLARE @v INT = 10

EXECUTE ステートメントの引数と戻り値の型

パラメーターと引数

CREATE PROCEDURE p1 (@p1 INT) AS
GO
EXECUTE p1 100
EXECUTE @v1 = p1 100

RETURN ステートメント

RETURN 式に互換性のあるデータ型があること

CREATE FUNCTION f1() RETURNS INT
AS
BEGIN
  RETURN 100
END

MERGE ステートメント条件

条件がブール型であること

MERGE t1 USING t2
ON t1.c1 = t2.c2
WHEN t1.c1 > 10 THEN DELETE

違反の修正方法

データ型の割り当てを一貫性のあるものにし、必要に応じて型を明示的に変換することで、これらの問題を回避し、解決できます。 明示的にデータ型を変換する方法の詳細については、Microsoft Web サイトの「CAST および CONVERT (Transact-SQL)」を参照してください。

警告を抑制する状況

この種類の警告は抑制しないでください。

使用例

この例では、テーブルにデータを挿入する 2 つのストアド プロシージャが示されています。 1 つ目のプロシージャ procWithWarning は、データ型の暗黙的な変換を発生させます。 2 つ目のプロシージャ 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

参照

概念

データベース コードの分析によるコードの品質の向上