このリクエストを実行する:
update table t1 set t1.column = 0 where t1.column2 = 1234
このエラーを取得する:
リレーション「テーブル」の列「t1」は存在しません
このリクエストはMySQLで正常に実行されます。
なぜPostgreSQLでこのエラーが発生するのですか?
それがあなたの望む構文かどうかはわかりません。 構文でUPDATE
を確認します
現在、それは
[ WITH [ RECURSIVE ] with_query [, ...] ]
UPDATE [ ONLY ] table_name [ * ] [ [ AS ] alias ]
SET { column_name = { expression | DEFAULT } |
( column_name [, ...] ) = ( { expression | DEFAULT } [, ...] ) |
( column_name [, ...] ) = ( sub-SELECT )
} [, ...]
[ FROM from_list ]
[ WHERE condition | WHERE CURRENT OF cursor_name ]
[ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]
したがって、table t1
を指定すると、table
という名前のテーブルとして解析されます。実際には、それを行うには引用符"table" t1
で囲む必要があります。
テキストデータを作成してみましょう
CREATE TABLE "table" AS
SELECT x AS column, x AS column2
FROM generate_series(1,12345) AS t(x);
これで、元のクエリを試し、元の結果を取得できます。
UPDATE "table" t1 SET t1.column=0 WHERE t1.column2=1234;
ERROR: column "t1" of relation "table" does not exist
LINE 1: UPDATE "table" t1 SET t1.column=0 WHERE t1.column2=1234;
そして、それはあなたが得ている問題です。テーブルと同様に、SQLキーワードを使用する場合は、引用符で囲む必要があります。興味深いことに、ここではそれだけでは不十分です。
UPDATE "table" t1 SET t1."column"=0 WHERE t1.column2=1234;
ERROR: column "t1" of relation "table" does not exist
LINE 1: UPDATE "table" t1 SET t1."column"=0 WHERE t1.column2=1234;
さらに、列が予約済みキーワードであるかどうかに関係なく、テーブルのエイリアスはSETリストではサポートされませんのようです。
UPDATE "table" t1 SET "column"=0 WHERE t1.column2=1234;
なぜエイリアスを使用できないのですか、IRCのxocolatlが役立ちます。
<xocolatl> EvanCarroll:=の左側にあるエイリアスを使用できない理由は複合型のためにです
<xocolatl> EvanCarroll:バグではなくWADです
したがって、カスタムの複合型を持つテーブルをCREATE
するコードでは、UPDATE
を実行します。
CREATE TYPE foo AS ( x int, y int );
CREATE TABLE foobar AS
SELECT v::foo AS mycol
FROM ( VALUES (1,2), (2,100) ) AS v;
UPDATE foobar SET mycol.x = 9;
したがって、.
を許可する構文はmycol.type-address
であり、tablealias.col-name
ではありません。
それが意味をなさない場合、この動作以外の動作はあいまいな構文を与えるでしょう。
CREATE TYPE foo AS ( mycol int, x int );
CREATE TABLE mytable AS
SELECT v::foo AS mycol, 1 AS x
FROM ( VALUES (1,2), (2,100) ) AS v;
UPDATE mytable AS mycol SET mycol.x = 9;
mycol.x
は何を指しますか? notがあいまいなため、テーブル参照とテーブルエイリアスは無効になっているため、mycol
という名前の複合型は、テーブルmytable
で常に100%の時間です。
それはPostgresの奇妙さです。 UPDATE
のドキュメントに記載されているように、テーブル名はターゲット列に使用しないでください。
column_name
table_name
という名前のテーブルの列の名前。列名は、必要に応じて、サブフィールド名または配列添え字で修飾できます。 ターゲット列の指定にテーブルの名前を含めないでください—たとえば、UPDATE table_name SET table_name.col = 1
は無効
UPDATE
句で更新できるテーブルは1つだけなので、ステートメントを誤って解釈する余地はありません。