2010-11-17 8 views
45

Wir werden unseren Kunden ein Tool zur Verfügung stellen, das (unter anderem) eine neue SQL Server-Datenbank erstellt, und ich möchte eine grundlegende Validierung für den von ihnen bereitgestellten Datenbanknamen durchführen können. Die SQL Server-Dokumentation erläutert, welche Zeichen in einem Datenbanknamen gültig sind. Die Dokumentation ist jedoch offensichtlich falsch, weil ich erfolgreich Datenbanken erstellen kann, deren Namen die dokumentierten Regeln verletzen.Welche Zeichen sind in einem SQL Server-Datenbanknamen gültig?

Laut der SQL Server-Dokumentation für CREATE DATABASE müssen Datenbanknamen den Regeln für Kennungen entsprechen. und die Regeln für identifiers hängen vom Datenbankkompatibilitätsgrad ab. Wenn der Kompatibilitätsgrad 100 ist (was laut SQL Server Management Studio "SQL Server 2008" bedeutet), muss der Name mit einem Unicode-Buchstaben beginnen: _, @ oder #; gefolgt von einem oder mehreren Buchstaben, Zahlen, @, $, oder _. Die Dokumentation besagt eindeutig, dass eingebettete Leerzeichen oder Sonderzeichen nicht zulässig sind.

Dies steht in krassem der verfügbaren Beweise, weil ich SQL Server Management Studio verwenden, können eine Datenbank, deren Name This & That | "Other" zu schaffen - die nicht nur enthält eingebettete Leerzeichen (explizit verboten), aber Sonderzeichen enthält (|, "), die in einem Dateinamen nicht einmal gültig sind. Ich überprüfte, und der Kompatibilitätsgrad der Datenbank ist in der Tat "SQL Server 2008 (100)", obwohl der Name auf dieser Kompatibilitätsstufe als ungültig dokumentiert ist.

Heck, kann ich selbst tun CREATE DATABASE " " (ja, das ist ein Leerzeichen), was beweist, dass das erste Zeichen tut nicht haben einen Brief an sein, unterstreichen, um Zeichen oder Pfund-Zeichen.

Also meine Frage ist, welche Zeichen sind in einem SQL Server-Datenbanknamen gültig? Gibt es dokumentierte Regeln, die mit dem tatsächlichen Verhalten von SQL Server übereinstimmen?

+4

Was ist der Wert bei der Verwendung von ungültigen oder extrem ungewöhnlichen Zeichen für eine Datenbank, Tabelle, etc Name? Anders als sicherzustellen, dass diejenigen, die Ihre Datenbank verwenden müssen, Ihren Namen verfluchen ... –

+2

Es liegt an den Benutzern zu entscheiden, wie die Datenbank aufgerufen werden soll. Wenn sie einen elenden Namen wählen wollen, ist mein Verständnis in diesem Punkt, dass wir sie nicht aufhalten wollen. (Das kann sich ändern, aber ich möchte zumindest wissen, womit wir arbeiten müssen.) –

Antwort

26

Der rules for identifiers Zustand am Ende:

Wenn Kennungen verwendet werden, in Transact-SQL-Anweisungen, die Kennungen, die durch doppelte Anführungszeichen oder Klammern begrenzt werden nicht mit diesen Regeln entsprechen müssen. immer mit doppelten Anführungszeichen oder Klammern

Durch einen Datenbanknamen zu wählen, die diese Regeln nicht entsprechen, Sie haben sie umschließen.

Wenn die Regeln für reguläre Bezeichner beachtet werden, können Sie Ihren Datenbanknamen ohne Anführungszeichen verwenden.

Die folgenden Anweisungen sind ok

CREATE DATABASE [conformingName] 
CREATE DATABASE conformingName 
CREATE DATABASE [This & That | "Other"] 

aber nicht

CREATE DATABASE This & That | "Other" 

EDIT:

Ich bin damit einverstanden, dass dies nicht, wie ist, würde man die verknüpfte Dokumentation verstehen: Was in Einklang steht muss mit den Regeln für Bezeichner bedeuten, wenn die Regeln nicht mehr gelten, sobald die Kennung beigefügt ist? Der Punkt über das Einschließen von nicht übereinstimmenden Bezeichnern sollte Teil der Regeln sein.

+4

Okay, ich verstehe. Aber die Dokumente scheinen nichts darüber zu sagen, was in diesen Zitaten gültig ist und was nicht. Bedeutet das * alles * geht? Illegale Unicode-Zeichen? '\ 0'? Oder gibt es noch Regeln? –

+5

Probieren Sie es aus! Ja, alles geht. Ich habe einen Datenbanknamen mit dem Namen ~ '^% $ £" erstellt. –

10

Es gibt einen Unterschied zwischen regulären Bezeichnern und begrenzten Bezeichnern. Ein regulärer Bezeichner ist an die von Ihnen genannten Einschränkungen gebunden, während ein begrenzter Bezeichner beliebige Zeichen (mit Ausnahme des Trennzeichens) enthalten kann.

Da Sie Anführungszeichen um den Bezeichner verwenden, handelt es sich um einen begrenzten Bezeichner, und Sie sind nicht durch die Regeln regulärer Bezeichner eingeschränkt.

Ohne die Trennzeichen können Sie nur Datenbanken mit Kennungen erstellen, die die Regeln der regulären Bezeichner folgen:

create database db_name 

mit Begrenzungszeichen, können Sie so ziemlich alles verwenden:

create database "That's a funny name, isn't it?" 

create database [)(/%Q)/#&%¤)Q/#)!] 
+2

Erklären *, während ein begrenzter Bezeichner beliebige Zeichen ** außer ** dem Begrenzer * enthalten kann. Ich kann das Zeichen einfach zweimal eingeben, um es zu umgehen: ** create Datenbank "" "" ** oder sogar ** create database []]] ** – Pacerier

+1

@Pacerier: Ja, wenn Begrenzungs-IDs das Escapen unterstützen, können Sie sogar den Begrenzer in der ID verwenden. – Guffa

6

Persönlich würde ich begrenzen sie zum Alphabet und zu den Zahlen und nichts sonst (gut möglicherweise auch ein _). Keine Leerzeichen, keine lustigen Symbole, keine Wagenrückgabe usw. Das ist das Sicherste, was Sie tun können.

+4

macht überhaupt keinen Sinn. Genau wie ist es sicherer? – Pacerier

+3

Es ist wahr, dass es in Bezug auf das Ausführen von Skripten gegen die Datenbank sicherer ist, die keine Sonderzeichen berücksichtigen können. –

+7

@Pacerier, Sie wissen nie, welches System oder welcher Code Ihren verrückten Datenbanknamen irgendwann verarbeiten könnte explodieren, weil du Charaktere benutzt hast, deren Entwickler zu kurzsichtig war, auch wenn SQL Server mit ihnen OK ist – ProfK

2

Getrennte Namen - umgeben von eckigen Klammern oder doppelten Anführungszeichen (wenn QUOTED_IDENTIFIER auf ON gesetzt ist) - können grundsätzlich alles andere als die Trennzeichen selbst enthalten. Es ist sogar möglich, die Begrenzer innerhalb des Namens mit einer Escape-Logik zu verwenden. Beachten Sie jedoch, dass nur das abschließende Escapezeichen maskiert werden muss. Im ersten Beispiel unten muss die einzelne Instanz des öffnenden Escape-Zeichens im Namen nicht maskiert werden, während das schließende Escape-Zeichen maskiert werden muss (indem die einzelne Instanz durch zwei ersetzt wird). Ich denke, die Logik hier ist, dass jeder Code, der diese Anweisungen analysiert, nach einem schließenden Escape-Zeichen sucht und nicht daran interessiert ist, verschachtelte öffnende Escape-Zeichen zu verwenden.

  • [Test [Test] -> Test [Test
  • [Test]] Test] -> Test] Test

Es folgt eine Beschreibung der Regeln umgebenden nicht begrenzt (nonquoted) Bezeichnernamen in SQL Server 2012. Es ist ein Auszug aus dem Dokument Guide to Migrating from MySQL to SQL Server 2012.

Schema Objektnamen

In SQL Server 2012 kann ein Objektnamen bis zu 128 Zeichen lang sein.

Nonquoted Bezeichnernamen müssen diese Regeln befolgen:

  • Das erste Zeichen muss alphanumerisch sein, ein Unterstrich (_), ein at-Zeichen (@) oder ein Nummernzeichen (#).
  • Nachfolgende Zeichen können alphanumerische Zeichen, Unterstriche, ein (@) Zeichen, ein Nummernzeichen oder ein Dollarzeichen enthalten.
  • Der Bezeichner darf kein reserviertes Transact-SQL-Wort sein. Leitfaden zur Migration von MySQL nach SQL Server 2012 8
  • Eingebettete Leerzeichen oder Sonderzeichen sind nicht zulässig.

Bezeichner, die mit @ oder einem Nummernzeichen beginnen, haben spezielle Bedeutungen. Bezeichner, die mit @ beginnen, sind lokale Variablennamen. Diejenigen, die mit einem Nummernzeichen starten, sind temporäre Tabellennamen.

Um einen Bezeichnernamen in Transact-SQL zu zitieren, müssen Sie die eckigen Klammern ([]) verwenden.