Странное поведение в Postgresql - PullRequest
5 голосов
/ 05 января 2012

Я новичок в 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

, когда я запускаю запрос через Cпрограмма, использующая libpq:

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.

1 Ответ

13 голосов
/ 05 января 2012

Ваша update_tbl_point функция, вероятно, выполняет что-то вроде этого:

new.last_update = current_timestamp;

, но она должна использовать new."Last_Update", поэтому исправьте функцию триггера.

Имена столбцов нормализуется в нижнем регистре в PostgreSQL (противоположно тому, что говорит стандарт SQL), но идентификаторы, заключенные в двойные кавычки, сохраняют свой регистр:

Кавычка идентификатора также делает его чувствительным к регистру,тогда как имена без кавычек всегда складываются в нижний регистр.Например, идентификаторы FOO, foo и "foo" в PostgreSQL считаются одинаковыми, но "Foo" и "FOO" отличаются друг от друга.(Свертывание имен без кавычек в нижний регистр в 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;

, и он будет работать, потому что все три формы нормализованы до eggs.Однако, если вы сделаете это:

create table pancakes (
    "Eggs" integer not null
)

, то вы можете сделать это:

update pancakes set "Eggs" = 11;

, но не это:

update pancakes set eggs = 11;

Обычная практика с PostgreSQL:везде использовать строчные идентификаторы, чтобы вам не пришлось об этом беспокоиться.Я бы порекомендовал такую ​​же схему именования и в других базах данных, так как необходимость заключать все в кавычки просто оставляет вас в куче двойных кавычек (стандартных), обратных кавычек (MySQL) и скобок (SQL Server) в вашем SQL, и это несделать вас друзьями.

...