SR0014: Potrebbe verificarsi una perdita di dati durante l'esecuzione del cast da {Tipo1} a {Tipo2}.
RuleId |
SR0014 |
Category |
Microsoft.Design |
Breaking Change |
Non sostanziale |
Causa
Il tipo di dati per una colonna, variabile o parametro viene convertito in modo implicito in un altro tipo di dati.
Descrizione della regola
Se ai tipi di dati vengono assegnati in modo incoerente alle colonne, variabili o parametri, vengono implicitamente convertiti quando il codice Transact-SQL che contiene quegli oggetti viene eseguito. Questo tipo di conversione non solo riduce la prestazione ma, in alcuni casi, causa anche una perdita minima di dati. Ad esempio, un'analisi della tabella potrebbe essere in esecuzione se è necessario convertire ogni colonna in una clausola WHERE. Peggio, i dati potrebbero essere persi se una stringa Unicode viene convertita in una stringa ASCII che utilizza una tabella di codici diversa.
Questa regola fa NOT:
Controllare il tipo di una colonna calcolata perché il tipo non è conosciuto fino alla fase di esecuzione.
Analizzare qualsiasi cosa in un'istruzione CASE. Non analizza inoltre il valore restituito di un'istruzione CASE.
Analizzare i parametri di input o il valore restituito di una chiamata a ISNULL
Oggetti CLR SQL
Per gli oggetti Common Language Run-time (SQL CLR) SQL Server, vengono eseguiti i seguenti controlli:
Tipo Object |
Verifica compatibilità dei tipi |
Verifica potenziale perdita di dati |
---|---|---|
Colonne |
Sì |
No |
Parametri di funzioni e procedure archiviate |
No |
No |
Variabili. |
No |
No |
Tipi XML |
No |
No |
Quando si assegna un oggetto a un altro ed entrambi sono tipi di oggetti CLR SQL, devono essere dello stesso tipo o un avviso sarà generato. È possibile convertire in modo esplicito solo il seguente a un tipo di oggetto CLR SQL o viene visualizzato un avviso: binary, varbinary, char, nchar, varchar o nvarchar.
Funzioni di sistema
Il tipo restituito viene verificato per le seguenti funzioni di 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
Nessun controllo viene eseguito per assicurarsi che gli input sono validi nel contesto della funzione ad eccezione di LEFT, RIGHT, CONVERTe delle funzioni CAST. Ad esempio, non viene visualizzato alcun avviso per SUM(tipo datetime2) in quanto l'analisi del codice del database non comprende che tipo di input è previsto dalla funzione SUM. Sarà visualizzato un avviso è se c'è un problema con l'espressione di input stessa, ad esempio se è stato specificato SUM(money + real).
Controlli specifici che vengono eseguiti
Nella tabella seguente vengono descritti gli specifici controlli, con un esempio per ognuno:
Costrutto di linguaggio |
Ciò che viene controllato |
Esempio |
---|---|---|
Valore predefinito dei parametri |
Tipo di dati dei parametri |
|
Predicato CREATE INDEX |
Il predicato è Boolean |
|
Argomenti di funzioni LEFT o RIGHT |
Lunghezza e tipo di argomento di tipo stringa |
|
Argomenti di funzioni CAST e CONVERT |
Espressione e tipi sono validi |
|
Istruzione SET |
Lato sinistro e lato destro dispongono di tipi compatibili |
|
Predicato istruzione IF |
Il predicato è Boolean |
|
Predicato istruzione WHILE |
Il predicato è Boolean |
|
Istruzione INSERT |
Valori e colonne sono corretti |
![]()
I caratteri jolly non vengono verificati.Ad esempio: INSERT INTO t1 SELECT * FROM t2
|
Predicato SELECT WHERE |
Il predicato è Boolean |
|
Espressione SELECT TOP |
L'espressione è un Integer o un tipo float |
|
Istruzione UPDATE |
Espressione e colonna dispongono di tipi compatibili |
|
Predicato UPDATE |
Il predicato è Boolean |
|
Espressione UPDATE TOP |
L'espressione è un Integer o un tipo float |
|
DELETE PREDICATE |
Il predicato è Boolean |
|
Espressione DELETE TOP |
L'espressione è un Integer o un tipo float |
|
Dichiarazione variabile DECLARE. |
Valore iniziale e tipo di dati sono compatibili |
|
Tipi restituiti e argomenti dell'istruzione EXECUTE |
Parametri e argomenti |
|
Istruzione RETURN |
L'espressione RETURN dispone di un tipo di dati compatibile |
|
L'istruzione MERGE condiziona |
La condizione è Boolean. |
|
Come correggere le violazioni
È possibile evitare e risolvere questi problemi assegnando costantemente tipi di dati e convertendo in modo esplicito tipi dove sono necessari. Per ulteriori informazioni su come convertire esplicitamente i tipi di dati, vedere la pagina sul sito Web Microsoft CAST e CONVERT (Transact-SQL).
Esclusione di avvisi
Non escludere questo tipo di avviso.
Esempio
In questo esempio vengono mostrate due stored procedure che inseriscono dati in una tabella. La prima routine, procWithWarning, causerà una conversione implicita di un tipo di dati. La seconda procedura, procFixed, mostra come è possibile aggiungere una conversione esplicita per ottimizzare le prestazioni e mantenere tutti i dati.
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
Vedere anche
Concetti
Analisi del codice di database per migliorare la qualità del codice