2012-01-05 14 views
5

Sono nuovo di Postgresql e sto provando a migrare la mia applicazione da MySQL.
Ho una tabella con la seguente struttura:Strane abitudini in 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 

quando si esegue la query attraverso un programma C utilizzando libpq:

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

ho ottenuto il seguente risultato:

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

Ottengo esattamente lo stesso errore quando provo a cambiare il valore di "Execute" o di qualsiasi altra colonna usando pgAdminIII.

Tutto funziona correttamente se cambio il nome della colonna da "Last_Update" a "last_update".

Ho trovato lo stesso problema con le altre tabelle che ho nel mio database e la colonna appare sempre con le colonne di riepilogo o timestamp.

risposta

13

La vostra funzione update_tbl_point sta probabilmente facendo qualcosa di simile:

new.last_update = current_timestamp; 

ma dovrebbe essere utilizzato in modo new."Last_Update" risolvere il tuo funzione di trigger.

nomi di colonna sono normalized to lower case in PostgreSQL (il contrario di quello che dice lo standard SQL si badi bene), ma gli identificatori che vengono doppia quotate mantengono il loro caso:

Citando un identificatore anche lo rende tra maiuscole e minuscole, mentre i nomi non quotati sono sempre piegato in minuscolo. Ad esempio, gli identificatori FOO, foo e "foo" sono considerati uguali da PostgreSQL, ma "Foo" e "FOO" sono diversi da questi tre e l'altro. (Il ripiegamento dei nomi non quotati in minuscolo in PostgreSQL è incompatibile con lo standard SQL, che dice che i nomi non quotati devono essere piegati in maiuscolo, quindi foo dovrebbe essere equivalente a "FOO" e non "foo" secondo lo standard. si vuole scrivere applicazioni portatili si consiglia di citare sempre un particolare nome o mai citarlo)

quindi, se fate questo:.

create table pancakes (
    Eggs integer not null 
) 

allora si può fare uno di questi:

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

e funzionerà perché tutte e tre le forme sono normalizzate a eggs. Tuttavia, se si esegue questa operazione:

create table pancakes (
    "Eggs" integer not null 
) 

allora si può fare questo:

update pancakes set "Eggs" = 11; 

ma non questa:

update pancakes set eggs = 11; 

La pratica di consueto con PostgreSQL è quello di utilizzare gli identificatori minuscole ovunque in modo che non devi preoccuparti di questo. Suggerirei lo stesso schema di denominazione anche in altri database, dovendo citare tutto ciò ti lascia solo un casino di doppi apici (standard), backtick (MySQL) e parentesi (SQL Server) nel tuo SQL e che non lo faranno farti degli amici

+0

Grazie amico mio! La tua spiegazione è stata impeccabile! Alexandra. – user1131031