4 Stimmen

Vermeiden von TSQL-Datenkonvertierungsfehlern

Ich denke, diese Frage lässt sich am besten in Form eines einfachen Beispiels beantworten. Das folgende SQL-Stück verursacht eine "DB-Library Error:20049 Severity:4 Message:Data-conversion resulted in overflow" 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 

Inwiefern unterscheidet sich dies von:

select 1.000000/(1.000000/1.000000)
go

was gut funktioniert?

4voto

John Rudy Punkte 36386

Als ich das letzte Mal versuchte, Sybase zu verwenden (vor vielen Jahren), hatte ich das gleiche Problem. Da ich von einer SQL Server-Mentalität herkomme, war mir nicht klar, dass Sybase versuchen würde, die Dezimalstellen herauszuzwingen - was mathematisch gesehen das ist, was es sollte tun. :)

Von der Sybase-Handbuch :

Arithmetische Überlauffehler treten auf, wenn der neue Typ zu wenig Dezimalstellen hat Stellen hat, um die Ergebnisse unterzubringen.

Und weiter unten:

Bei impliziten Konvertierungen in numerische Werte oder Dezimaltypen erzeugt der Verlust der Skala einen Skalenfehler. Verwenden Sie die Option Option arithabort numeric_truncation um festzulegen, wie schwerwiegend ein solcher Fehler betrachtet wird. Die Standardeinstellung, arithabort numeric_truncation on, bricht die Anweisung ab, die den Fehler verursacht, fährt aber mit der Verarbeitung anderer Anweisungen in der Transaktion oder Stapel. Wenn Sie arithabort numeric_truncation ausschalten, wird Adaptive Server die Abfrageergebnisse abschneiden und setzt die Verarbeitung fort.

Así que in der Annahme, dass der Verlust an Präzision in Ihrem Szenario akzeptabel ist wollen Sie wahrscheinlich zu Beginn Ihrer Transaktion Folgendes wissen:

SET ARITHABORT NUMERIC_TRUNCATION OFF

Und dann am Ende der Transaktion:

SET ARITHABORT NUMERIC_TRUNCATION ON

Das war die Lösung für mich vor vielen Jahren ...

1voto

Patrick Szalapski Punkte 7759

Dies ist nur eine Spekulation, aber könnte es sein, dass das DBMS nicht den dynamischen Wert Ihrer Variablen betrachtet, sondern nur die potenziellen Werte? So könnte eine sechsstellige numerische Zahl geteilt durch eine sechsstellige numerische Zahl eine zwölfstellige numerische Zahl ergeben; bei der buchstäblichen Division weiß das DBMS, dass es keinen Überlauf gibt. Ich bin mir immer noch nicht sicher, warum das DBMS sich darum kümmert - sollte es nicht das Ergebnis von zwei sechsstelligen Divisionen als bis zu einer 18-stelligen Zahl zurückgeben?

1voto

Brody Punkte 2076

Da Sie die Variablen im ersten Beispiel deklariert haben, wird erwartet, dass das Ergebnis die gleiche Deklaration hat (d.h. numerisch (18,6)), was aber nicht der Fall ist.

Ich muss sagen, dass die erste in SQL2005 funktionierte (gab 1.000000 [der gleiche deklarierte Typ] zurück), während die zweite (1.00000000000000000000000 [eine völlig andere Deklaration]) zurückgab.

0voto

dumle Punkte 59

Hat zwar nicht direkt etwas damit zu tun, könnte aber möglicherweise jemandem etwas Zeit mit den arithmetischen Überlauffehlern bei Sybase ASE (12.5.0.3) sparen.

Ich habe einige Standardwerte in einer temporären Tabelle festgelegt, die ich später aktualisieren wollte, und bin dabei über einen arithmetischen Überlauffehler gestolpert.

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 an:

Arithmetic overflow during implicit conversion of NUMERIC value '100.000' to a NUMERIC field .

Was in meinem Kopf funktionieren sollte, aber nicht funktioniert, da die Spalte "thenumber" nicht deklariert wurde (oder indirekt als decimal(4,3) deklariert wurde). Sie müssten also indirekt die Spalte der temporären Tabelle mit Skalierung und Genauigkeit in dem gewünschten Format deklarieren, in meinem Fall war es 000.000.

select 000.000 as thenumber into #test --this solved it

Hoffentlich spart das jemandem etwas Zeit :)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X