SR0014: Perda de dados pode ocorrer quando a projeção de {Tipo1} para {Tipo2}

RuleId

SR0014

<strong>Categoria</strong>

Microsoft.design

Alteração significativa

Não-separável

Causa

O tipo de dados para uma coluna, variável ou parâmetro está sendo convertido implicitamente em outro tipo de dados.

Descrição da regra

Se os tipos de dados inconsistentemente recebem colunas, variáveis ou parâmetros, eles são implicitamente convertidos quando o Transact-SQL que contém os objetos de código é executar. Este tipo de conversão não apenas reduz o desempenho, mas também, em alguns casos, faz com que sutis perda de dados. Por exemplo, uma verificação de tabela pode executar se cada coluna em uma cláusula WHERE deve ser convertida. Pior ainda, os dados podem ser perdidos se uma seqüência de caracteres Unicode é convertida em uma seqüência de caracteres ASCII que usa uma página de código diferente.

Esta regra não:

  • Verifique o tipo de uma coluna computada porque o tipo não é conhecido até o tempo de execução.

  • Analise tudo dentro de uma instrução CASE. Ele também não analisa o valor de retorno de uma instrução CASE.

  • Analisar os parâmetros de entrada ou retornar o valor de uma chamada para ISNULL

Objetos CLR de SQL

Para SQL Server objetos do Common Language Runtime (CLR SQL), as verificações a seguintes são realizadas:

Tipo de objeto

Verifica a compatibilidade do tipo

Verifica o potencial de perda de dados

Colunas

Sim

Não

Procedimento armazenado e parâmetros da função

Não

Não

As variáveis

Não

Não

Tipos XML

Não

Não

Quando você atribuir um objeto para outro e ambos são tipos de objetos CLR de SQL, eles devem ser do mesmo tipo ou um aviso será gerado. Você pode converter explicitamente apenas o seguinte um tipo de objeto CLR em SQL ou será exibido um aviso: binary, varbinary, char, nchar, varchar, or nvarchar.

Funções do sistema

Tipo de retorno está marcado para as seguintes funções de sistema: @@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, and ISNULL.

ObservaçãoObservação

Nenhuma verificação é realizada para garantir que as entradas sejam válidas no contexto de função, exceto o LEFT, RIGHT, CONVERT, e CAST funções. Por exemplo, nenhum aviso aparecerá para SUM(tipo datetime2) porque a análise de código do banco de dados não entende o tipo de entrada é esperado pelo SUM função. Aparecerá um aviso é se há um problema com a expressão de entrada, por exemplo, se você tiver especificado SUM(dinheiro + real).

Verificações específicas que são executadas.

A tabela a seguir descreve as verificações específicas que são executadas com um exemplo para cada:

Construção de linguagem

O que é verificado.

Exemplo

Valor padrão de parâmetros

Tipo de dados de parâmetro

CREATE PROCEDURE p1(
@p1 INT = 1)
AS
BEGIN
END

Predicado de CREATE INDEX

Predicado é booleano

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

Argumentos de funções da esquerda ou direita

Tipo de argumento de seqüência de caracteres e comprimento

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

Argumentos de funções CAST e CONVERT

Expressão e tipos são válidos

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

Instrução SET

Esquerda e direita tem tipos compatíveis

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

Predicado de instrução IF

Predicado é booleano

IF (@v > 10)

ENQUANTO o predicado de instrução

Predicado é booleano

WHILE (@v > 10)

Instrução de inserção

Colunas e os valores estão corretas

INSERT INTO t1(c1, c2) VALUES (99, 'xyz')
INSERT INTO t1 SELECT c1 FROM t2.
ObservaçãoObservação
Curingas não são verificados.Por exemplo: INSERT INTO t1 Selecionar * FROM t2

Selecione onde predicado

Predicado é booleano

SELECT * FROM t1 WHERE c1 > 10

Expressão de SELECT TOP

Expressão é um tipo inteiro ou Float

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

Instrução de atualização

Expressão e a coluna tem tipos compatíveis

UPDATE t1 SET c1 = 100

Predicado de atualização

Predicado é booleano

UPDATE t1 SET c1 = 100 
WHERE c1 > 100

Expressão de atualização superior

Expressão é um tipo inteiro ou Float

UPDATE TOP 4 table1

EXCLUIR PREDICADO

Predicado é booleano

DELETE t1 WHERE c1 > 10

Expressão de excluir superior

Expressão é um tipo inteiro ou Float

DELETE TOP 2 FROM t1

DECLARAR a declaração de variável

Tipo de valor e os dados inicial são compatíveis

DECLARE @v INT = 10

EXECUTAR argumentos de instrução e tipo de retorno

Parâmetros e argumentos

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

Instrução RETURN

Expressão de retorno tem um tipo de dados compatíveis

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

MESCLAR as condições de instrução

Condição é booleano

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

Como corrigir violações

Você pode evitar e resolver esses problemas, atribuindo consistentemente os tipos de dados e convertendo explicitamente tipos onde são necessários. Para obter mais informações sobre como converter explicitamente os tipos de dados, consulte esta página no site da Microsoft: CAST e CONVERT (Transact-SQL).

Quando suprimir avisos

Você não deve suprimir esse tipo de aviso.

Exemplo

Este exemplo mostra dois procedimentos armazenados para inserir dados em uma tabela. O primeiro procedimento, procWithWarning, fará com que uma conversão implícita de um tipo de dados. O segundo procedimento, procFixed, mostra como você pode adicionar uma conversão explícita para maximizar o desempenho e reter todos os dados.

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

Consulte também

Conceitos

Analisando o código do banco de dados para melhorar a qualidade do código