SR0014: Se pueden perder datos cuando se convierte de {Tipo1} a {Tipo2}
Identificador de regla |
SR0014 |
Categoría |
Microsoft.Design |
Cambio problemático |
Poco problemático |
Causa
El tipo de datos de una columna, variable o parámetro se convierte implícitamente en otro tipo de datos.
Descripción de la regla
Si los tipos de datos están asignados incoherentemente a columnas, variables o parámetros, implícitamente se convierten cuando se ejecuta el código de Transact-SQL que contiene esos objetos. Este tipo de conversión no solo reduce el rendimiento, si no que también, en algunos casos, produce una leve pérdida de datos. Por ejemplo, un examen de la tabla se podría ejecutar si se debe convertir cada columna de una cláusula WHERE. Lo que es peor, se podrían perder los datos si una cadena Unicode se convierte en una cadena ASCII que utiliza una página de código diferente.
Esta regla NO lo hace:
Compruebe el tipo de una columna calculada porque el tipo no se conoce hasta el tiempo de ejecución.
Analiza nada dentro de una instrucción CASE. Tampoco analiza el valor devuelto de una instrucción CASE.
Analiza los parámetros de entrada o el valor devuelto de una llamada a ISNULL
Objetos CLR de SQL
Para los objetos de Common Language Run-time (SQL CLR) de SQL Server, se realizan las comprobaciones siguientes:
Object (Tipo) |
Comprueba la compatibilidad de tipos |
Comprueba la pérdida de datos potencial |
---|---|---|
Columnas |
Sí |
No |
Procedimiento almacenado y parámetros de función |
No |
No |
Variables |
No |
No |
Tipos XML |
No |
No |
Si asigna un objeto a otro y ambos son tipos de objeto CLR de SQL, deben ser del mismo tipo o se generará una advertencia. Solo puede convertir explícitamente lo siguiente a un tipo de objeto CLR de SQL o aparecerá una advertencia: binary, varbinary, char, nchar, varchar o nvarchar.
Funciones del sistema
Se comprueba el tipo de valor devuelto para las siguientes funciones del 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 e ISNULL.
Nota
No se realiza ninguna comprobación para asegurarse de que las entradas son válidas en el contexto de función salvo para las funciones LEFT, RIGHT, CAST y CONVERT. Por ejemplo, no aparece ninguna advertencia para SUM (tipo datetime2) porque el análisis del código de base de datos no entiende qué tipo de entrada espera la función SUM. Una advertencia aparecerá es si hay un problema con la propia expresión de entrada, por ejemplo si especificara SUM (dinero + real).
Comprobaciones concretas que se realizan
En la tabla siguiente se describen las comprobaciones concretas que se realizan, con un ejemplo de cada una:
Construcción de lenguaje |
Qué se comprueba |
Ejemplo |
---|---|---|
Valor predeterminado de parámetros |
Tipo de datos de parámetro |
|
Predicado CREATE INDEX |
El predicado es booleano |
|
Argumentos de las funciones LEFT o RIGHT |
Tipo y longitud del argumento de cadena |
|
Argumentos de las funciones CONVERT y CAST |
La expresión y los tipos son válidos |
|
SET (instrucción) |
El lado izquierdo y el derecho tienen tipos compatibles |
|
Predicado de la instrucción IF |
El predicado es booleano |
|
Predicado de la instrucción WHILE |
El predicado es booleano |
|
Instrucción INSERT |
Los valores y columnas son correctos |
Nota
No se comprueban los caracteres comodín.Por ejemplo: INSERT INTO t1 SELECT * FROM t2
|
SELECT WHERE (predicado) |
El predicado es booleano |
|
SELECT TOP (expresión) |
La expresión es de un tipo Float o Integer |
|
Instrucción UPDATE |
La expresión y la columna tienen tipos compatibles |
|
Predicado UPDATE |
El predicado es booleano |
|
Expresión UPDATE TOP |
La expresión es de un tipo Float o Integer |
|
PREDICADO DELETE |
El predicado es booleano |
|
Expresión DELETE TOP |
La expresión es de un tipo Float o Integer |
|
Declaración de la variable DECLARE |
El valor inicial y el tipo de datos son compatibles |
|
Argumentos de la instrucción EXECUTE y tipo de valor devuelto |
Parámetros y argumentos |
|
RETURN (instrucción) |
La expresión RETURN tiene un tipo de datos compatible |
|
Condiciones de la instrucción MERGE |
La condición es booleana |
|
Cómo corregir infracciones
Puede evitar y resolver estos problemas asignando los tipos de datos de forma coherente y convirtiendo los tipos explícitamente donde se necesitan. Para obtener más información sobre cómo convertir explícitamente tipos de datos, vea esta página en el sitio web de Microsoft: CAST and CONVERT (Transact-SQL).
Cuándo suprimir advertencias
No debería suprimir este tipo de advertencia.
Ejemplo
En este ejemplo se muestran dos procedimientos almacenado que insertan datos en una tabla. El primer procedimiento, procWithWarning, producirá una conversión implícita de un tipo de datos. El segundo procedimiento, procFixed, muestra cómo puede agregar una conversión explícita para maximizar el rendimiento y retener todos los datos.
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
Vea también
Conceptos
Analizar el código de base de datos para mejorar la calidad del código