Precisione, scala e lunghezza (Transact-SQL)

Si applica a:SQL Server database SQL di Azure Istanza gestita di SQL di Azure Azure Synapse Analytics AnalyticsPlatform System (PDW)SQL analytics endpoint in Microsoft FabricWarehouse in Microsoft Fabric

La precisione è il numero di cifre in un numero. La scala è il numero di cifre a destra della virgola decimale in un numero. Ad esempio, il numero 123.45 ha una precisione di 5 e una scala di 2.

In SQL Server la precisione massima predefinita dei tipi di dati numeric e decimal è 38.

La lunghezza di un tipo di dati numerico è il numero di byte utilizzati per l'archiviazione del numero. Per varchar e char, la lunghezza di una stringa di caratteri è il numero di byte. Per nvarchar e nchar, la lunghezza della stringa di caratteri è il numero di coppie di byte. La lunghezza per i tipi di dati binary, varbinary e image è il numero di byte. Il tipo di dati int può ad esempio contenere 10 cifre, viene archiviato in 4 byte e non consente l'uso dei decimali. Il tipo di dati int ha una precisione pari a 10, una lunghezza pari a 4 e una scala pari a 0.

  • Quando si concatenano due espressioni char, varchar, binary o varbinary , la lunghezza dell'espressione risultante è la somma delle lunghezze delle due espressioni di origine, fino a 8.000 byte.

  • Quando si concatenano due espressioni nchar o nvarchar , la lunghezza dell'espressione risultante è la somma delle lunghezze delle due espressioni di origine, fino a 4.000 coppie di byte.

  • Quando si confrontano due espressioni dello stesso tipo di dati ma lunghezze diverse usando UNION, EXCEPTo INTERSECT, la lunghezza risultante è più lunga delle due espressioni.

Osservazioni:

La precisione e la scala dei tipi di dati numerici, ad eccezione di decimal, sono fisse. Quando un operatore aritmetico collega due espressioni dello stesso tipo, il risultato è costituito dallo stesso tipo di dati, con la precisione e la scala definiti per tale tipo. Se un operatore collega due espressioni con tipi di dati numerici diversi, il tipo di dati del risultato viene stabilito dalle regole relative alla precedenza dei tipi di dati. La precisione e la scala del risultato corrispondono a quelle definite per il tipo di dati.

Nella tabella seguente vengono descritti i criteri per il calcolo della precisione e della scala del risultato, quando il risultato di un'operazione è di tipo decimal. Il risultato è decimal quando si verifica una delle condizioni seguenti:

  • Entrambe le espressioni sono di tipo decimal.
  • Un'espressione è di tipo decimal e l'altra è di un tipo di dati con precedenza inferiore rispetto a decimal.

Le espressioni operandi sono indicate come espressione e1, con precisione p1 e scala s1, ed espressione e2, con precisione p2 e scala s2. La precisione e la scala per qualsiasi espressione che non è decimale è la precisione e la scala definite per il tipo di dati dell'espressione. La funzione max(a, b) indica di accettare il valore maggiore di a o b. Analogamente, min(a, b) indica di accettare il valore minore di a o b.

Operazione Precisione del risultato Scala dei risultati 1
e1 + e2 max(s1, s2) + max(p1 - s1, p2 - s2) + 1 max(s1, s2)
e1 - e2 max(s1, s2) + max(p1 - s1, p2 - s2) + 1 max(s1, s2)
e1 * e2 p1 + p2 + 1 s1 + s2
e1 / e2 p1 - s1 + s2 + max(6, s1 + p2 + 1) max(6, s1 + p2 + 1)
e1 { UNION | EXCEPT | INTER edizione Standard CT } e2 max(s1, s2) + max(p1 - s1, p2 - s2) max(s1, s2)
e1 % e2 min(p1 - s1, p2 - s2) + max(s1, s2) max(s1, s2)

1 La precisione e la scala dei risultati hanno un massimo assoluto di 38. Quando la precisione del risultato è superiore a 38, viene ridotta a 38 e la scala corrispondente viene ridotta per evitare il troncamento della parte intera del risultato. In alcuni casi, ad esempio la moltiplicazione o la divisione, il fattore di scala non viene ridotto per mantenere la precisione decimale, anche se l'errore di overflow può essere generato.

Oltre alle operazioni di sottrazione, è necessario max(p1 - s1, p2 - s2) archiviare la parte integrante del numero decimale. Se non c'è spazio sufficiente per archiviarli (vale a dire ), max(p1 - s1, p2 - s2) < min(38, precision) - scalela scala viene ridotta per fornire spazio sufficiente per la parte integrale. La scala risultante è min(precision, 38) - max(p1 - s1, p2 - s2), quindi la parte frazionaria può essere arrotondata per adattarsi alla scala risultante.

Nelle operazioni di moltiplicazione e divisione sono necessarie le posizioni precision - scale per archiviare la parte integrale del risultato. La scala può essere ridotta tramite le regole seguenti:

  1. La scala risultante viene ridotta a min(scale, 38 - (precision-scale)) se la parte integrale è minore di 32, perché non può essere maggiore di 38 - (precision-scale). Il risultato potrebbe essere arrotondato in questo caso.
  2. La scala non viene modificata se è minore di 6 e se la parte integrale è maggiore di 32. In questo caso, potrebbe essere generato un errore di overflow se non può rientrare in decimal(38, scale).
  3. La scala è impostata su 6 se è maggiore di 6 e se la parte integrale è maggiore di 32. In questo caso, sia la parte integrale che la scala verrebbero ridotte e il tipo risultante è decimal(38, 6). Il risultato potrebbe essere arrotondato a 6 cifre decimali oppure viene generato l'errore di overflow se la parte integrale non può rientrare in 32 cifre.

Esempi

L'espressione seguente restituisce il risultato senza arrotondamento, perché il risultato può rientrare in decimal(38, 17):The following expression returns result 0.00000090000000000 without rounding, because the result can fit into decimal(38, 17):

SELECT CAST(0.0000009000 AS DECIMAL(30, 20)) * CAST(1.0000000000 AS DECIMAL(30, 20)) [decimal(38, 17)];

In questo caso la precisione è 61e la scala è 40.

La parte (precision-scale = 21) integrale è minore di 32, quindi questo caso è il primo caso nelle regole di moltiplicazione e la scala viene calcolata come min(scale, 38 - (precision-scale)) = min(40, 38 - (61-40)) = 17. Il tipo di risultato è decimal(38, 17).

L'espressione seguente restituisce il risultato 0.000001 per adattarsi a decimal(38, 6):

SELECT CAST(0.0000009000 AS DECIMAL(30, 10)) * CAST(1.0000000000 AS DECIMAL(30, 10)) [decimal(38, 6)];

In questo caso la precisione è 61e la scala è 20.

La scala è maggiore di 6 e la parte integrale (precision-scale = 41) è maggiore di 32. Questo caso è il terzo caso nelle regole di moltiplicazione e il tipo di risultato è decimal(38, 6).

Vedi anche