6

私はPostgresqlを初めて使用し、MySQLからアプリケーションを移行しようとしています。
次の構造のテーブルがあります。

                            Table "public.tbl_point"
          Column         |         Type          | Modifiers | Storage  | Description
 ------------------------+-----------------------+-----------+----------+-------------
  Tag_Id                 | integer               | not null  | plain    |
  Tag_Name               | character varying(30) | not null  | extended |
  Quality                | integer               | not null  | plain    |
  Execute                | integer               | not null  | plain    |
  Output_Index           | integer               | not null  | plain    |
  Last_Update            | abstime               |           | plain    |
Indexes:
"tbl_point_pkey" PRIMARY KEY, btree ("Tag_Id")
Triggers:
add_current_date_to_tbl_point BEFORE UPDATE ON tbl_point FOR EACH ROW EXECUTE PROCEDURE update_tbl_point()
Has OIDs: no

libpqを使用してCプログラムでクエリを実行すると、次のようになります。

UPDATE tbl_point SET "Execute"=0 WHERE "Tag_Id"=0

次の出力が得られました。

ERROR:  record "new" has no field "last_update"
CONTEXT:  PL/pgSQL function "update_tbl_point" line 3 at assignment

pgAdminIIIを使用して「実行」または他の列の値を変更しようとすると、まったく同じエラーが発生します。

列名を「Last_Update」から「last_update」に変更すると、すべて正常に機能します。

データベースにある他のテーブルでも同じ問題が見つかりました。列は常にabstime列またはtimestamp列で表示されます。

4

1 に答える 1

14

あなたのupdate_tbl_point関数はおそらく次のようなことをしています:

new.last_update = current_timestamp;

ただし、使用する必要があるnew."Last_Update"ため、トリガー機能を修正してください。

PostgreSQLでは列名は小文字に正規化されますが(SQL標準では逆になります)、二重引用符で囲まれた識別子は大文字と小文字を維持します。

識別子を引用すると大文字と小文字が区別されますが、引用符で囲まれていない名前は常に小文字になります。たとえば、識別子FOO、foo、および「foo」はPostgreSQLでは同じと見なされますが、「Foo」と「FOO」はこれら3つとは異なります。(PostgreSQLで引用符で囲まれていない名前を小文字に折りたたむことは、SQL標準と互換性がありません。つまり、引用符で囲まれていない名前は大文字に折りたたむ必要があります。したがって、fooは、標準では「foo」ではなく「FOO」と同等である必要があります。ポータブルアプリケーションを作成する場合は、常に特定の名前を引用するか、決して引用しないことをお勧めします。)

したがって、これを行う場合:

create table pancakes (
    Eggs integer not null
)

次に、これらのいずれかを実行できます。

update pancakes set eggs = 11;
update pancakes set Eggs = 11;
update pancakes set EGGS = 11;

3つの形式すべてがに正規化されているため、機能しeggsます。ただし、これを行う場合:

create table pancakes (
    "Eggs" integer not null
)

次に、これを行うことができます:

update pancakes set "Eggs" = 11;

しかし、これではありません:

update pancakes set eggs = 11;

PostgreSQLの通常の方法は、どこでも小文字の識別子を使用することです。これにより、心配する必要がなくなります。他のデータベースでも同じ命名スキームをお勧めします。すべてを引用する必要があると、SQLに二重引用符(標準)、バッククォート(MySQL)、角かっこ(SQL Server)が散らかってしまいます。友達になりましょう。

于 2012-01-05T00:29:01.577 に答える