Wie kann ich verhindern, dass Ganzzahlen in SQL Server stillschweigend in Sternchen umgewandelt werden?

8

Angenommen, wir haben ein Tabellenkonto, es gibt ein Feld acct_type varchar(2)

Insert into account(acct_type) values(888)

Ausgabe:

+-----------+
| acct_type |
+-----------+
| *         |
+-----------+

Ich erwarte, dass beim Auslösen der Anweisung ein Fehler ausgelöst wird. Warum speichert es *Wert in Tabelle?

Ankush
quelle
@SMor: oder vielleicht ist die Tabelle falsch definiert. Wenn die Anwendung dort Zahlen (Ganzzahlen) speichern möchte, sollte die Spalte möglicherweise integeralsvarchar
a_horse_with_no_name

Antworten:

11

Für den varcharDatentyp wird ein abgeschnittener Wert wie intfolgt ausgegeben, *anstatt einen Fehler auszulösen (in diesem Fall, da die drei Ziffern nicht in a passen varchar(2)).

Dies passiert nicht mit nvarchar

Es gibt keine Möglichkeit, dieses Verhalten zu ändern. Es wird aus Gründen der Abwärtskompatibilität beibehalten. Wenn dies ein echtes Problem für Sie ist, können Sie eine Prüfbedingung hinzufügen, dass der Wert in der Spalte nicht ist, *aber ich kann mir keine Situation vorstellen, in der es sich wirklich lohnt, dies zu tun.

Die Lösung ist einfach, das nicht zu tun. Wenn Sie eine einfügen müssen, INTüberprüfen Sie diese zuerst im Bereich -9 to 99. Oder verwenden Sie immer Anführungszeichen um Werte, die für eine Zeichenfolgenspalte bestimmt sind, anstatt sich auf implizite Konvertierungen zu verlassen.

Martin Smith
quelle
Danke Martin! .. Wie kann ich eine Prüfbedingung setzen, um zu verhindern, dass ein ganzzahliger Wert in varchar abgelegt wird ... können Sie mir bitte beim Schreiben der Syntax helfen?
Ankush
ALTER TABLE account ADD CONSTRAINT CK_NoStar_acct_type CHECK (acct_type <> '*')aber Sie müssen dies mit ziemlicher Sicherheit nicht tun. Es gibt eine Menge char/varcharwild lebender Säulen mit einer Länge von 10oder weniger, wo dies eine theoretische Möglichkeit ist, die ohne das gut auskommt. Die Prüfbeschränkung blockiert natürlich auch eine explizite Einfügung von, *da sie nicht unterscheiden kann, wie sie erreicht *wurde
Martin Smith
1
Vielen Dank Martin !! Jetzt kann ich meinem Entwickler die Syntax und die Nebeneffekte davon richtig erklären
Ankush
4
Ich denke, die eigentliche Frage ist: Wenn sie ganzzahlige Werte speichern möchten, warum ist dies dann ein varcharAnfang?
a_horse_with_no_name
@a_horse_with_no_name Wenn Sie eine Frage an das OP haben, setzen Sie diese auf die Frage und nicht auf eine Antwort. Sie werden hier nicht benachrichtigt. Ich würde sagen, es gibt nichts in der Frage, was darauf hindeutet, dass sie immer nur Ganzzahlen in dieser Spalte speichern wollen, obwohl "888" varchar(2)ohnehin kein gültiger Wert für das ist. Alles, was gefolgert werden kann, ist, dass sie es mindestens einmal versucht haben und ein unerwartetes Ergebnis erhalten haben, das sie lieber falsch gemacht hätten, als stillschweigend zu scheitern.
Martin Smith
-2

varchar accept string type. Sie können einen Wert zwischen '' Symbolen einfügen. sieht aus wie Insert into account(acct_type) values('888') Aber es wird ein Fehler angezeigt, da die maximale Länge 2 beträgt. icrease varchar length oder Ihre maximale Wertlänge muss 2 seinInsert into account(acct_type) values('88')

Əşrəf Cəfərli
quelle
Ihre Antwort geht in eine andere Richtung als die Frage. Sami gibt an, dass kein Fehler angezeigt wird, und gibt den Wert '*' ein. Der Kommentar, den SMor abgegeben hat, geht eher in Richtung des Problems.
Mark