2012-11-04 10 views
9
で「列の 『x』は存在しません」文字列リテラルのエラーを「X」

可能性の重複:
Column ‘mary’ does not existPostgreSQLの

私は受け入れることができる値を確認する必要がありますチェック制約を介した列。私はチェック制約を使う必要があります、これは大学の割り当てのためです。

このコードを使用して、制約を作成してテーブルに追加します。ここで

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’)); 

は私が取得エラーです:

ERROR: column "’verkehrsunfall’" does not exist 

私は列の試みが得ることができる値を確認しようとして、それはverkehrsunfall列と列の標準を比較しようとすると、このエラー、からなるにつれ( 'Verkehrsunfall'、 'Hochwasser'、 'Sonstiges')の文字列の1つです。

これは、私たちの講師が講義で私たちに示したのとまったく同じ構文です。チェックとvarcharsを比較することが可能かどうかわかりませんか?または私は何を間違っているのですか?ここで

は講義からの例です:

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

これはおそらく同じコース教材からですか(http://stackoverflow.com/q/13196572/398670)ですか?タイミングは、ワードプロセッサでSQLを編集し、PDFまたはWebページのメモとして学生がコピーして貼り付けた講師かもしれないようです。 –

+1

正しい一重引用符を使用すると正しい構文になります。 http://www.sqlfiddle.com/#!12/fb4ec –

+1

あなたの命名規則は良くありません。 first_nameのようなスコアの下で使うか、あまり理想的ではないルートを "FirstName"にすることができますか?大文字とアンダースコアを混同したり、一致させたりしないでください。これは名前を付けるのが一般的ですが、ポストグルに特有のことですが、スコアの下では単語を区切り、大文字は使用しません。 – Kuberchaun

答えて

19

あなたのテキストエディタやワープロが'のように、、ではない普通の単一引用符のように、いわゆるスマート引用符を使用しています。リテラルには通常の単一引用符(実際はアポストロフィ)'を使用し、識別子には二重引用符"を使用します。構文エラーを引き起こすかもしれない奇妙なコンマもあります。 the PostgreSQL manual on SQL syntax、具体的にはlexical structureを参照してください。

ワードプロセッサでは、SQL(または他のソースコード)を編集しないでください。 Notepad++、BBEdit、vimなどのまともなテキストエディタでは、このようにSQLをマングルしません。

正しい例:

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

それはあからさまな構文エラーが発生しない理由 - 、代わりにあなたの既存のない列に関する奇妙なエラーメッセージを表示します - PostgreSQLはUnicodeの列名を受け入れ、と考えているためであります文字識別子の完全に有効な文字。お守り:

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

をこのように、あなたはtestという名前の列があり、’test’という名前の列を求める場合、PostgreSQLが正しく’test’という名前の列が存在しないことを教えてくれます。あなたのケースでは、リテラル文字列Verkehrsunfallを代わりに使用しようとしたときに’verkehrsunfall’という列を要求しているため、列’verkehrsunfall’が終了しないというエラーメッセージが表示されます。

本当の一重引用符であれば、無効な構文になります。第1は、閉じられていない一重引用符を持つため、psqlでは全く実行されません。 2ndは次のようなもので失敗します:

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

...なぜなら、ANSI SQLでは、識別子としてリテラルを使用しようとしているからです。正しい構文は、すべての識別子または引用符なしのため、二重引用符で次のようになります。

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

あなたはまた、varchar型のtypmod内の不要なスペースを持っています。 varchar(3 0)は無効です:ところで

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

、PostgreSQLでは、それは代わりにvarchar型のtext列を使用する方が良いでしょう。アプリケーションまたは検証の理由で長さ制約が必要な場合は、length(colname)に検査制約を追加します。

+0

ありがとう、このような細かいことは、2つの異なるASCIIコードに対応しているとは思いません。 –

+0

@LuciusRutiliusLupusちょうどニットピック:両方が実際にASCIIではありません。一重引用符(実際はアポストロフィ)はありますが、 ''はASCIIの範囲にない' \ u2019'です。彼らは異なる文字コードまたはユニコードコードポイント、確かに。 –