2012-01-05 24 views
5

Jestem nowy w Postgresql i próbuję przenieść moją aplikację z MySQL.
Mam tabeli z następującą strukturę:Dziwne zachowanie w Postgresql

      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 

kiedy uruchomić kwerendę poprzez program C z wykorzystaniem libpq:

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

Mam następujący wynik:

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

Dokładnie taki sam błąd występuje przy próbie zmiany wartości "Execute" lub dowolnej innej kolumny za pomocą pgAdminIII.

Wszystko działa poprawnie, jeśli zmieniam nazwę kolumny z "Last_Update" na "last_update".

Znalazłem ten sam problem z innymi tabelami, które mam w mojej bazie danych, a kolumna zawsze pojawia się z kolumnami abstime lub timestamp.

Odpowiedz

13

Twoja funkcja update_tbl_point jest prawdopodobnie robi coś takiego:

new.last_update = current_timestamp; 

ale należy przy użyciu new."Last_Update" więc naprawić swoją funkcję wyzwalania.

Nazwy kolumn są normalized to lower case in PostgreSQL (przeciwieństwem tego, co średnia SQL mówi pamiętajcie), ale identyfikatory, które są podwójnie cytowane utrzymać swoją sprawę:

Cytowanie identyfikator także sprawia, że ​​wielkość liter, natomiast nazwy nienotowane są zawsze złożone do małej litery. Na przykład identyfikatory FOO, foo i "foo" są uważane za takie same przez PostgreSQL, ale "Foo" i "FOO" różnią się od tych trzech i siebie nawzajem. (Składanie niecytowanych nazw do małych liter w PostgreSQL jest niezgodne ze standardem SQL, który mówi, że niecytowane nazwy powinny być składane na duże litery, więc foo powinno być równoważne "FOO", a nie "foo" zgodnie ze standardem. chcesz pisać aplikacje przenośne radzimy zawsze podawać konkretną nazwę lub nie cytować go)

Tak, jeśli to zrobisz.

create table pancakes (
    Eggs integer not null 
) 

następnie można wykonać jedną z nich:

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

i będzie działać, ponieważ wszystkie trzy formy są znormalizowane do eggs. Jednakże, jeśli to zrobić:

create table pancakes (
    "Eggs" integer not null 
) 

następnie można to zrobić:

update pancakes set "Eggs" = 11; 

ale nie w ten sposób:

update pancakes set eggs = 11; 

Normalną praktyką z PostgreSQL jest stosowanie niższych identyfikatory przypadków wszędzie abyś nie musiał się tym martwić. Poleciłbym ten sam schemat nazewnictwa również w innych bazach danych, ponieważ cytowanie wszystkiego pozostawia po sobie bałagan podwójnych cytatów (standard), backticks (MySQL) i nawiasów (SQL Server) w twoim SQL i to nie będzie uczynić was przyjaciółmi.

+0

Dziękuję, mój przyjacielu! Twoje wyjaśnienie było bezbłędne! Alexandra. – user1131031