Під час переходу «Корпорація 2» на PostgreSQL ми прагнули зберегти роботу також із MySQL та Firebird. Це вимагало перевірки SQL окремо для кожної СУБД.
Початковий запит із нотатки:
select MK.KARTA_ID, MK.P_BALANS, MK.P_VLASN, MK.P_ZALOG, MK.P_UGON,
MK.MARKA_ID MARKA_ID,MK.VID_ID, MK.ZAV_NOMER ZAV_NOMER, MK.DVIG_NOMER DVIG_NOMER, MK.NSHAS, MK.YEAR_PROD, MK.SER_SVID SER_SVID, MK.DATA_SVID, MK.SER_ZNAK, MK.DATE_NUM, MK.KOD_F, MK.KOD_USER, MK.OLD_ID, MK.DATA_EDIT, MK.DATE_INSERT, MK.DATE_DELETE, MK.IS_DELETED, MK.DATE_COMPILE, MK.DATE_UPDATE, MK.ID_REGION_KOD ID_REGION_KOD, MK.ID_RAJON ID_RAJON, MK.ID_VID, MK.ID_KOD_F, MK.NAME_ORG NAME_ORG, MK.NAME_VID NAME_VID, MK.UPPER_ZAV_NOMER, MK.UPPER_DVIG_NOMER, MK.UPPER_NSHAS, MK.UPPER_SER_SVID, MK.UPPER_SER_ZNAK, MK.DATA_SPISAN, MK.ADDR_ORG, MK.P_REG, MK.DATA_FIRST_REG, MK.D_OLDSVID, MK.N_OLDSVID, MK.YEAR_SVID, MK.YEAR_NUM, MK.YEAR_SPISAN, MK.YEAR_FIRST_REG,MK.YEAR_
OLDSVID, MK.DATA_BALANS, MK.REGION_BALANS, MK.RAJON_BALANS, R.REGION_NAME, MO.KOD_EDRPO, MO.N_PASSP from MTP_KARTA MK
left join TBLREGIONS R
on MK.ID_REGION_KOD=R.ID_REGION_KOD
left join MTP_ORG MO
on (MK.ID_KOD_F=MO.ID_KOD_F)
and (MK.ID_REGION_KOD=MO.ID_REGION_KOD)
where (MK.MARKA_ID<>') and (MK.DATA_SPISAN is null)
and(MK.NAME_ORG like '%трактор%')
order by MARKA_ID
limit 0, 50
Данный запрос прекрасно работает в MySQL, но совершенно не работает в PostgreSQL.
Запропонований тоді варіант:
select MK.KARTA_ID, MK.P_BALANS, MK.P_VLASN, MK.P_ZALOG, MK.P_UGON,
MK.MARKA_ID as MARKA_ID,
MK.VID_ID,
MK.ZAV_NOMER as ZAV_NOMER,
MK.DVIG_NOMER as DVIG_NOMER, MK.NSHAS, MK.YEAR_PROD,
MK.SER_SVID as SER_SVID, MK.DATA_SVID, MK.SER_ZNAK, MK.DATE_NUM, MK.KOD_F, MK.KOD_USER, MK.OLD_ID, MK.DATA_EDIT, MK.DATE_INSERT, MK.DATE_DELETE, MK.IS_DELETED, MK.DATE_COMPILE,
MK.DATE_UPDATE, MK.ID_REGION_KOD as ID_REGION_KOD,
MK.ID_RAJON as ID_RAJON, MK.ID_VID, MK.ID_KOD_F,
MK.NAME_ORG as NAME_ORG,
MK.NAME_VID as NAME_VID, MK.UPPER_ZAV_NOMER,
MK.UPPER_DVIG_NOMER, MK.UPPER_NSHAS, MK.UPPER_SER_SVID, MK.UPPER_SER_ZNAK, MK.DATA_SPISAN, MK.ADDR_ORG, MK.P_REG, MK.DATA_FIRST_REG, MK.D_OLDSVID, MK.N_OLDSVID, MK.YEAR_SVID, MK.YEAR_NUM, MK.YEAR_SPISAN, MK.YEAR_FIRST_REG,MK.YEAR_OLDSVID, MK.DATA_BALANS, MK.REGION_BALANS, MK.RAJON_BALANS, R.REGION_NAME, MO.KOD_EDRPO, MO.N_PASSP
from MTP_KARTA MK
left join TBLREGIONS R
on MK.ID_REGION_KOD=R.ID_REGION_KOD
left join MTP_ORG MO
on (MK.ID_KOD_F=MO.ID_KOD_F)
and (MK.ID_REGION_KOD=MO.ID_REGION_KOD)
where (MK.MARKA_ID<>') and (MK.DATA_SPISAN is null)
and(MK.NAME_ORG like '%трактор%')
order by MARKA_ID
limit 50 offset 10
Обидва фрагменти збережено для аналізу, але в них є незавершений рядковий літерал у MK.MARKA_ID<>'. У першому також розірвано ім’я YEAR_OLDSVID. У такому вигляді це не перевірені робочі запити.
AS робить псевдонім явним, але для звичайного псевдоніма стовпця не завжди обов’язковий у PostgreSQL. Істотна відмінність прикладів — синтаксис пагінації: MySQL підтримує LIMIT offset, count і LIMIT count OFFSET offset, тоді як PostgreSQL використовує другий варіант. При цьому LIMIT 0, 50 та LIMIT 50 OFFSET 10 вибирають різні сторінки, а не однаковий результат.
Не слід автоматично вважати LIMIT універсальним синтаксисом для всіх SQL-серверів, зокрема Firebird. Для перенесення також перевіряють типи, регістр, порівняння тексту та стабільність ORDER BY.
Документація: PostgreSQL SELECT, MySQL SELECT. Конкретну схему таблиць і тестові дані в нотатці не наведено.