Vermeiden TSQL Datenkonvertierungsfehler
-
03-07-2019 - |
Frage
Ich denke, das am besten in Form eines einfachen Beispiels gefragt. Das folgende Stück von SQL bewirkt, dass ein "DB-Library-Fehler: 20049 Severity: 4 Nachricht: Daten-Konvertierung in Überlauf geführt" Nachricht, aber wie kommt das?
declare @a numeric(18,6), @b numeric(18,6), @c numeric(18,6)
select @a = 1.000000, @b = 1.000000, @c = 1.000000
select @a/(@b/@c)
go
Wie ist das anders an:
select 1.000000/(1.000000/1.000000)
go
, die funktioniert?
Lösung
Ich lief in das gleiche Problem, das letzte Mal habe ich versucht, Sybase (vor vielen Jahren) zu verwenden. Ich stamme aus einer SQL Server-Einstellung, habe ich nicht erkennen, dass Sybase die Dezimalstellen zu zwingen versuchen würde, aus - was mathematisch, ist das, was es sollte zu tun. :)
Von der Sybase manuell :
Arithmetischer Überlauffehler auftreten, wenn der neue Typ hat zu wenig dezimal Orte, um die Ergebnisse zu berücksichtigen.
Und weiter unten:
Bei der impliziten Konvertierung in numerischen oder Dezimaltypen, Verlust der Skala erzeugt einen Skalierungsfehler. verwenden Sie die arithabort numeric_truncation Option um zu bestimmen, wie ernst ein solcher Fehler gilt als. Die Standardeinstellung, ARITHABORT numeric_truncation auf, bricht die Aussage, dass die Ursachen Fehler aber weiterhin andere zu verarbeiten, Anweisungen der Transaktion oder Stapel. Wenn Sie setzen arithabort numeric_truncation off, Adaptives Server kürzt die Abfrageergebnisse und weiter verarbeitet werden.
So unter der Annahme, dass der Verlust an Präzision in Ihrem Szenario akzeptabel , möchten Sie wahrscheinlich die folgenden am Anfang Ihrer Transaktion:
SET ARITHABORT NUMERIC_TRUNCATION OFF
Und dann am Ende Ihrer Transaktion:
SET ARITHABORT NUMERIC_TRUNCATION ON
Dies ist, was es für mich vor vielen vielen Jahren gelöst ...
Andere Tipps
Dies ist nur Spekulation, aber es könnte sein, dass das DBMS auf dem dynamischen Wert Ihrer Variablen sieht nicht, sondern nur die möglichen Werte? Somit wird ein sechs dezimal numerische von einem sechs dezimal numerischen aufgeteilt in zwölf dezimal numerischen führen könnte; im wörtlichen Teilung, weiß das DBMS gibt es keinen Überlauf. Immer noch nicht sicher, warum kümmern würde das DBMS, obwohl - shouldn't es das Ergebnis von zwei sechs Dezimalstellen Divisionen bis zu einem 18-dezimal numerischen zurückgeben
Da Sie die Variablen im ersten Beispiel erklärt haben, das Ergebnis wird erwartet, dass die gleichen Erklärung sein (das heißt numeric (18,6)), aber es ist nicht.
ich, dass die erste in SQL2005 arbeitete allerdings zu sagen haben (zurück 1.000000 [Das gleiche deklarierten Typ]), während der zweite zurück (1,00000000000000000000000 [A total andere Erklärung]).
nicht direkt, sondern könnte möglicherweise jemand einige Zeit mit den arithmetischen Überlauffehlern mit Sybase ASE (12.5.0.3) speichern.
Ich war ein paar Standardwerte in einer temporären Tabelle Einstellung, die ich später aktualisieren sollte, und stolperte auf einen arithmetischen Überlauffehler.
declare @a numeric(6,3)
select 0.000 as thenumber into #test --indirect declare
select @a = ( select thenumber + 100 from #test )
update #test set thenumber = @a
select * from #test
Zeigt den Fehler:
Arithmetic overflow during implicit conversion of NUMERIC value '100.000' to a NUMERIC field .
Was in meinem Kopf arbeiten sollte, aber nicht als ‚thenumber‘ Säule wurde nicht deklariert (oder indirekt als Dezimalzahl erklärt (4,3)). So müßte man indirekt die temporären Tabellenspalt mit Skalierung und Präzision, um das Format erklären Sie wollen, wie in meinem Fall 000.000 waren.
select 000.000 as thenumber into #test --this solved it
Hoffentlich, dass jemand etwas Zeit spart:)