IsNumeric fehlgeschlagen mit "Beim aktuellen Befehl ist ein schwerwiegender Fehler aufgetreten." SQL Server 2014 CTE

8

Ich führe eine Reihe von Skripten, die eine Datenbank generieren. Sie werden auf SQL Server 2012 (11.0.5058.0) ausgeführt. Auf SQL Server 2014 (12.0.4213.0) ein Skript Fehler mit:

  

Nachricht 0, Ebene 11, Status 0, Zeile 0
  Beim aktuellen Befehl ist ein schwerwiegender Fehler aufgetreten. Die Ergebnisse, falls vorhanden, sollten verworfen werden.

     

Nachricht 0, Ebene 20, Status 0, Zeile 0
  Beim aktuellen Befehl ist ein schwerwiegender Fehler aufgetreten. Die Ergebnisse, falls vorhanden, sollten verworfen werden.

Es scheint, dass die Verwendung der Ergebnisse einer IsNumeric -Anweisung in einer CTE-Abfrage das Erstellen von Abfragen unterbricht, da keine Zeilen erforderlich sind, um den Fehler zu verursachen. Eine gekürzte Version des Falles, in den ich geriet, ist:

%Vor%

Der einfachste Fall, den ich finden kann, ist:

%Vor%

Ich habe die Fehlerstufen von Microsoft überprüft und es sieht so aus Wie 11 ist korrigierbar Benutzerfehler und 20 ist fataler Fehler, so dass ich fühle, wie ich eine gemischte Nachricht bekomme.

Gibt es einen richtigen Weg dies zu tun oder ist es eine Regression im Jahr 2014?

    
npjohns 06.10.2015, 01:07
quelle

2 Antworten

2

Dies ist sicherlich ein Fehler.

Das CTE muss dieses Verhalten auch nicht erzeugen. Das Folgende, das den Ausdruck direkt verwendet, hat den gleichen Effekt.

%Vor%

Ich könnte über 12.0.2269.0 und 12.0.4213.0, aber nicht über 12.0.4449.0 reprografieren, so dass es aussieht, als sei es jetzt behoben.

Der relevante KB-Artikel mit Details ist ( FIX: Zugriffsverletzung, wenn eine Abfrage ISDATE- oder ISNUMERIC-Funktionen in Join-Bedingungen verwendet in SQL Server 2014 SP1 ).

Der Stack-Trace, wenn die Ausnahme ausgelöst wurde, liegt unterhalb (für die Durchsuchbarkeit)

%Vor%     
Martin Smith 05.05.2016, 22:12
quelle
1

Ich denke, es ist ein Fehler. Ich habe jedoch einen Workaround gefunden, der für Sie funktionieren könnte.

%Vor%

TRY_PARSE gibt NULL zurück, wenn die Umwandlung fehlschlägt. Wenn es also NOT NULL ist, dann weißt du, dass es ein int. ist.

Es gibt einige subtile Unterschiede zwischen den beiden Funktionen, aber ich bevorzuge trotzdem TRY_PARSE , weil dies laut ist MSDN

  

ISNUMERIC gibt 1 für einige Zeichen zurück, die keine Zahlen sind, wie z   Plus (+), Minus (-) und gültige Währungssymbole wie der Dollar   Zeichen ($)

UPDATE:

Ich sollte wahrscheinlich einen der feinen Unterschiede klären. ISNUMERIC gibt 1 zurück, wenn der Parameter zu irgendeinem numerischen Typ analysiert werden kann, und sie sind:

  • int
  • numerisch
  • bigint
  • Geld
  • smallint
  • kleines Geld
  • Tinyint
  • float
  • dezimal
  • real

Es ist nicht das gleiche wie TRY_PARSE , das versucht, die Eingabe in einen der obigen spezifischen Datentypen zu zerlegen. (In meinem Beispiel ist es INT ). Wenn Sie also ISNUMERIC wirklich nachahmen möchten, müssen Sie für jeden Typ einen verschachtelten (oder abgeflachten) CASE verwenden. Selbst dann kann Verhalten immer noch etwas unerwartet sein, aber das ist eine ganz andere Geschichte.

    
Stainy 05.05.2016 20:46
quelle