Странное поведение в Postgresql

postgresql quoted-identifier

2826 просмотра

1 ответ

28 Репутация автора

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

Автор: user1131031 Источник Размещён: 05.01.2012 12:11

Ответы (1)


13 плюса

367075 Репутация автора

Решение

Ваша 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, и это не будет сделать вас друзьями

Автор: mu is too short Размещён: 05.01.2012 12:29
Вопросы из категории :
32x32