Это сайт — моя персональная записная книжка. Интересна мне, по большей части, история, своя жизнь и немного программирование.

🚨 Особенности перехода с «Оракла» на «Постгрес»

В комментариях пообещал поописывать свой опыт перевода продукта с «Оракла» на «Постгрес», особенно в особенностях, которым очень мало уделено внимания на просторах интернета. Начну с простого, зато сразу целой пачкой. Примеры я, естественно, упростил, чтобы максимально выпукло продемонстрировать различия.

У нас довольно много генерируемых простых запросов, иногда они генерировались не очень аккуратно. «Оракл» такое прощает, а «Постгрес» — нет. Запрос, где одни и те же таблицы соединяются дважды «Постгресу» не по вкусу:

SELECT * FROM test INNER JOIN test1 USING(n) INNER JOIN test USING(n);

ERROR:  table name "test" specified more than once

«Постгрес» очень трепетно относится к тому, чтобы у подзапроса был алиас, даже если он потом нигде не используется:

SELECT * FROM (SELECT * FROM test);

ERROR:  subquery in FROM must have an alias
СТРОКА 1: SELECT * FROM (SELECT * FROM test);
                        ^
ПОДСКАЗКА:  For example, FROM (SELECT ...) [AS] foo.

В «Постгресе», в запросах на обновление нельзя указать алиас. Тут это логично, так как синтаксис подзапросов в этом случае у этой СУБД совершенно иной — они указываются в специальном месте.

UPDATE test t SET t.n=1;

ERROR:  column "t" of relation "test" does not exist
СТРОКА 1: UPDATE test t SET t.n=1;

Если «Оракл» спокойно относится к двум и более таблицам с одним алиасом, то «Постгресу» от этого плохеет. Жаль, иногда удобно объединить несколько таблиц алиасом прямо на месте и работать дальше с ним, как с единой таблицой.

SELECT t.n FROM test t, another_test t;

ERROR:  table name "t" specified more than once

В «Оракле» ключевое слово FROM не обязательно в запросах на удаление. У нас было несколько запросов без него.

DELETE test;

ERROR:  syntax error at or near "test"
СТРОКА 1: DELETE test;

В следующий раз буду описывать более комплексные примеры.

4 комментария
diaryea (diaryea.livejournal.com) 2016

Если мне не изменяет память, то еще в Постгресе версии 7.4 можно было спокойно обратиться к таблице, которой присвоен алиас по имени:

select * from tab t where t.foo = 123 -​-​ работает, что логично
select * from tab t where tab.foo = 123 -​-​ работало для 7.4

И получить, что интересно, совершенно разный результат.
Подробностей уже и не вспомню, к сожалению.

Евгений Степанищев (bolknote.ru) 2016

Комментарий для diaryea.livejournal.com:

Даже не представляю в чём могла бы быть разница. Разве что (это единственное предположение, которое может иметь хоть какой-то смысл) во втором случае выбиралась вся таблица.

Andrej Kudriavcev 2016

А почему именно Постгресс а не MySQL?

Евгений Степанищев (bolknote.ru) 2016

Комментарий для Andrej Kudriavcev:

Потому что у MySQL масса недостатков: недостаточный функционал, слабый оптимизатор запросов, проблемамы с производительностью репликации, плохая документация. Ещё где-то на «Хабре» была интересная статья про неконсистентность синтаксиса, но я не смог её найти.