2012-11-04 10 views
9

Eventuali duplicati:
Column ‘mary’ does not exist"Colonna 'x' non esiste" di errore per stringa letterale 'x' in PostgreSQL

ho bisogno di controllare i valori che possono essere accettate a una colonna attraverso un vincolo di controllo. Ho bisogno di usare il vincolo di controllo, perché questo è per un incarico del college.

Uso questo codice per creare e aggiungere il vincolo alla tabella.

CREATE TABLE Ereignis(
    E_Id Serial PRIMARY KEY, 
    Typ varchar(15), 
    Zeitpunkt timestamp, 
    Ort varchar(32), 
    Anzahl_Pers int 
); 

ALTER TABLE Ereignis ADD 
CONSTRAINT typ_ch CHECK (Typ in (’Verkehrsunfall’, ’Hochwasser’, ’Sonstiges’)); 

Ecco l'errore che ottengo:

ERROR: column "’verkehrsunfall’" does not exist 

Come ottengo da questo errore si cerca di confrontare colonna tip con la colonna Verkehrsunfall, dove, come cerco di controllare i valori colonna try può ottenere è una delle stringhe ('Verkehrsunfall', 'Hochwasser', 'Sonstiges').

Questa è esattamente la stessa sintassi che il nostro docente ci ha mostrato durante la conferenza. Non sono sicuro se sia possibile confrontare i varchar con il controllo? O cosa sto sbagliando?

Ecco l'esempio dalla lezione:

CREATE TABLE Professoren 
(PersNr INTEGER PRIMARYKEY, 
Name VARCHAR(3 0) NOT NULL , 
Rang CHAR(2) CHECK (Rang in ('C2' ,'C3' ,'C4')) , 
Raum INTEGER UNIQUE) ; 
+0

È questo (http://stackoverflow.com/q/13196572/398670) dallo stesso materiale del corso, forse? I tempi fanno sembrare che potrebbe essere un docente che ha modificato SQL in un elaboratore di testi e lo ha distribuito come PDF o note di pagine Web che gli studenti hanno copiato e incollato ... –

+1

La sintassi è corretta se si utilizzano le virgolette singole corrette: http://www.sqlfiddle.com/#!12/fb4ec –

+1

Solo una FYI la tua convenzione di denominazione non è buona. Utilizza i punteggi come first_name o se vuoi seguire la via meno ideale che puoi fare "FirstName". Non mescolare e abbinare maiuscole e caratteri di sottolineatura. Questo è generale per la denominazione, ma specifico per postgres: rimarrebbe sotto i punteggi per separare le parole e non usare maiuscole. – Kuberchaun

risposta

19

vostro editor di testo o word processor sta usando citazioni cosiddetti intelligenti, come , non virgolette singole ordinarie, come '. Utilizzare le virgolette singole ordinarie (apostrofi effettive) ' per i letterali o le doppie virgolette " per gli identificatori. Ci sono anche alcune virgole strane che possono causare errori di sintassi. Vedi the PostgreSQL manual on SQL syntax, in particolare lexical structure.

Non modificare SQL (o qualsiasi altro codice sorgente) in un elaboratore di testi. Un editor di testo decente come Notepad++, BBEdit, vim, ecc. Non manipolerà il tuo SQL in questo modo.

esempio Correzione:

CREATE TABLE Professoren 
(PersNr INTEGER PRIMARYKEY, 
Name VARCHAR(30) NOT NULL, 
Rang CHAR(2) CHECK (Rang in ('C2' ,'C3' ,'C4')), 
Raum INTEGER UNIQUE); 

La ragione per cui non causa un errore di sintassi a titolo definitivo - e invece ti dà un messaggio di errore strano la colonna non esistente - è perché PostgreSQL accetta i nomi delle colonne unicode e considera la carattere un carattere perfettamente valido per un identificatore. Osservare:

regress=> SELECT 'dummy text' AS won’t, 'dummy2' as ’alias’; 
    won’t | ’alias’ 
------------+--------- 
dummy text | dummy2 
(1 row) 

Quindi, se si dispone di una colonna chiamata test e chiedete la colonna denominata ’test’, PostgreSQL correttamente dire che non v'è alcuna colonna denominata ’test’. Nel tuo caso stai chiedendo una colonna denominata ’verkehrsunfall’ quando intendevi utilizzare la stringa letterale Verkehrsunfall invece, da qui il messaggio di errore che dice che la colonna ’verkehrsunfall’ non esce.

Se si trattasse di una singola citazione reale, sarebbe una sintassi non valida. Il primo non verrebbe eseguito in psql perché avrebbe una virgoletta singola non chiusa; il 2 ° fallirebbe con qualcosa del tipo:

regress=> SELECT 'dummy2' as 'alias'; 
ERROR: syntax error at or near "'alias'" 
LINE 1: SELECT 'dummy2' as 'alias'; 

...perché in ANSI SQL, si sta tentando di utilizzare un letterale come identificatore. La sintassi corretta sarebbe con virgolette per l'identificatore o senza virgolette a tutti:

regress=> SELECT 'dummy2' as "alias", 'dummy3' AS alias; 
alias | alias 
--------+-------- 
dummy2 | dummy3 
(1 row) 

Hai anche uno spazio indesiderato nel typmod varchar; varchar(3 0) non è valido:

regress=> SELECT 'x'::varchar(3 0); 
ERROR: syntax error at or near "0" 
LINE 1: SELECT 'x'::varchar(3 0); 

BTW, in PostgreSQL di solito è meglio usare una colonna text invece di varchar. Se si desidera un vincolo di lunghezza per motivi di applicazione o di convalida, aggiungere un vincolo di controllo su length(colname).

+0

Grazie mille, un dettaglio così piccolo che non mi rendo conto che corrispondono a 2 codici ASCII diversi. –

+0

@LuciusRutiliusLupus Solo un pignolo: in realtà non sono entrambi ASCII. Una singola citazione (apostrofo, in realtà) è, ma '' 'è' \ u2019' che non si trova nell'intervallo ASCII. Sono sicuramente codici di caratteri diversi o punti di codice Unicode. –

Problemi correlati