2010-11-17 18 views
45

Forniremo ai nostri clienti uno strumento che (tra le altre cose) crea un nuovo database SQL Server e voglio essere in grado di eseguire la convalida di base sul nome del database che forniscono. La documentazione di SQL Server spiega quali caratteri sono validi nel nome di un database. Tuttavia, la documentazione è apparentemente errata, perché posso creare database con nomi che violano le regole documentate.Quali caratteri sono validi in un nome di database di SQL Server?

In base alla documentazione di SQL Server per CREATE DATABASE, i nomi dei database devono essere conformi alle regole per gli identificatori; e le regole per identifiers dipendono dal livello di compatibilità del database. Quando il livello di compatibilità è 100 (che, secondo SQL Server Management Studio, significa "SQL Server 2008"), il nome deve iniziare con una lettera Unicode, _, @ o #; seguito da una o più lettere, numeri, @, $, # o _. La documentazione indica chiaramente che non sono consentiti spazi incorporati o caratteri speciali.

Questa vola di fronte delle prove disponibili, perché posso utilizzare SQL Server Management Studio per creare un database il cui nome è This & That | "Other" - che non solo contiene spazi incorporati (esplicitamente vietato), ma contengono caratteri speciali (|, ") che non sono nemmeno validi in un nome file. Ho controllato, e il livello di compatibilità del database è effettivamente "SQL Server 2008 (100)", anche se il suo nome è documentato come non valido a quel livello di compatibilità.

Heck, posso anche fare CREATE DATABASE " " (sì, che è un unico spazio), che dimostra che il primo carattere fa non devono essere una lettera, sottolineare, al segno, o cancelletto.

Quindi suppongo che la mia domanda sia, quali caratteri sono validi per in un nome di database di SQL Server? Esistono regole documentate coerenti con il comportamento effettivo di SQL Server?

+4

Qual è il valore nell'utilizzo di caratteri non validi o estremamente inusuali per un database, tabella, nome ecc.? Oltre a garantire che coloro che devono usare il tuo database maledicano il tuo nome ... –

+2

Spetterà agli utenti decidere cosa chiamare il database. Se vogliono scegliere un nome miserabile, la mia comprensione a questo punto è che non vogliamo fermarli. (Potrebbe cambiare, ma almeno voglio sapere con cosa dobbiamo lavorare.) –

risposta

26

Il rules for identifiers stato alla fine:

Quando identificativi vengono utilizzati in istruzioni Transact-SQL, le identificatori che non rispettano queste regole devono essere delimitati da virgolette doppie o parentesi.

Scegliendo un nome di database non conforme a tali regole, è necessario racchiuderlo sempre con virgolette doppie o parentesi.

Se le regole per gli identificatori regolari sono rispettate, è possibile utilizzare il nome del database senza virgolette/parentesi.

Le seguenti istruzioni sono ok

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

ma non

CREATE DATABASE This & That | "Other" 

EDIT:

Sono d'accordo che questo non è come si potrebbe capire la documentazione collegata: cosa vuol devono rispettare con le regole per gli identificatori significa se le regole non si applicano più appena l'identificatore è allegato? Il punto in cui inserire identificatori non conformi dovrebbe essere parte delle regole.

+4

Ok, capisco. Ma i documenti non sembrano dire nulla su ciò che è e non è valido all'interno di quelle citazioni. Significa che * qualsiasi cosa * va? Caratteri Unicode illegali? '\ 0 '? O ci sono ancora delle regole? –

+5

Provalo! Sì, tutto va bene. Ho creato un nome di database chiamato ~ '% $ £" –

10

C'è una differenza tra identificatori regolari e identificatori delimitati. Un identificatore regolare è vincolato alle limitazioni menzionate, mentre un identificatore delimitato può contenere qualsiasi carattere (eccetto il delimitatore).

Poiché si utilizzano le virgolette attorno all'identificatore, si tratta di un identificatore delimitato e non si dispone delle regole degli identificatori regolari.

Senza i delimitatori è possibile creare solo i database con identificatori che seguono le regole degli identificatori regolari:

create database db_name 

Con delimitatori, è possibile utilizzare praticamente qualsiasi cosa:

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

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

Spiega * mentre un identificatore delimitato può contenere qualsiasi carattere ** tranne ** il delimitatore *. Posso semplicemente digitare il carattere due volte per evitarlo, in quanto tale: ** creare database "" "" ** o anche ** crea database []]] ** – Pacerier

+1

@Pacerier: Sì, se gli identificatori delimitati supportano l'escaping, puoi anche usare il delimitatore nell'identificatore, – Guffa

6

Personalmente mi limiterei loro all'alfabeto e numeri e nient'altro (beh forse anche un _). Nessuno spazio, nessun simbolo divertente, nessun ritorno a capo ecc. Questo è il modo più sicuro che puoi fare.

+4

non ha alcun senso. esattamente come è più sicuro? – Pacerier

+3

È vero che è più sicuro in termini di script in esecuzione contro il database che non può prendere in considerazione caratteri speciali. –

+7

@Pacerier, non si sa mai quale sistema o codice potrebbe in un momento elaborare il nome del database whacky e esplodere perché hai usato i caratteri che lo sviluppatore era troppo miope per consentire, anche se SQL Server è OK con loro. – ProfK

2

Nomi delimitati - circondati da parentesi quadre o doppie virgolette (se QUOTED_IDENTIFIER è impostato su ON) - può contenere sostanzialmente qualsiasi cosa diversa dai delimitatori stessi. È persino possibile utilizzare i delimitatori all'interno del nome con una logica di escape. Si noti però che è solo il carattere di escape di chiusura che deve essere sfuggito. Nel primo esempio di seguito, la singola istanza del carattere di escape di apertura nel nome non ha bisogno di essere preceduta da escape mentre il carattere di escape di chiusura deve essere scappato (sostituendo la singola istanza con due). Immagino che la logica qui sia che qualsiasi codice che sta analizzando queste istruzioni sta cercando un carattere di escape di chiusura e non è interessato ai caratteri di escape di apertura nidificati.

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

La seguente è una descrizione delle regole che circondano non delimitato (nonquoted) nomi di identificatori in SQL Server 2012. È un estratto dal documento Guide to Migrating from MySQL to SQL Server 2012.

nomi di schema Object

In SQL Server 2012, il nome di un oggetto possono essere lunghi fino a 128 caratteri.

identificatori Nonquoted devono seguire queste regole:

  • Il primo carattere deve essere alfanumerico, un carattere di sottolineatura (_), un simbolo di chiocciola (@), o un simbolo di cancelletto (#).
  • I caratteri successivi possono includere caratteri alfanumerici, un trattino basso, un segno (@), un segno numerico o un segno di dollaro.
  • L'identificativo non deve essere una parola riservata Transact-SQL. Guida alla migrazione da MySQL a SQL Server 2012 8
  • Non sono consentiti spazi o caratteri speciali incorporati.

Gli identificatori che iniziano con @ o un segno di numero hanno significati speciali. Gli identificatori che iniziano con @ sono nomi di variabili locali. Quelle che iniziano con con un segno di numero sono nomi di tabelle temporanee.

Per citare un nome identificativo in Transact-SQL, è necessario utilizzare le parentesi quadre ([]).

Problemi correlati