SQL teu C ++, sarta lain JavaScript. Ku alatan éta, itungan éksprési logis lumangsung béda, sarta ieu teu hal anu sarua:
WHERE fncondX() AND fncondY()
= fncondX() && fncondY()
Dina prosés ngaoptimalkeun rencana palaksanaan query PostgreSQL , Entong ngitung sababaraha di antarana pikeun rékaman individu, hubunganana sareng kaayaan indéks anu diterapkeun ... Pondokna, cara panggampangna nyaéta nganggap yén anjeun teu bisa ngadalikeun dina urutan naon maranéhna bakal (jeung naha maranéhna bakal diitung pisan) sarua kaayaan.
Janten, upami anjeun masih hoyong ngatur prioritas, anjeun kedah nyusun éta nyieun kaayaan ieu unequal ngagunakeun kondisional и .

Data sareng damel sareng aranjeunna mangrupikeun dasarna , ku kituna penting pisan pikeun urang yén operasi dina aranjeunna dilaksanakeun henteu ngan ukur leres, tapi ogé éfisién. Hayu urang nempo conto husus dimana kasalahan dina ngitung ekspresi bisa dijieun, sarta dimana eta sia ngaronjatkeun efisiensi maranéhanana.
#0: RTFM
Ngawitan :
Nalika urutan evaluasi penting, éta bisa direbut ngagunakeun construct
CASE. Contona, ieu cara pikeun nyingkahan division ku nol dina kalimahWHEREteu bisa dipercaya:SELECT ... WHERE x > 0 AND y/x > 1.5;Pilihan aman:
SELECT ... WHERE CASE WHEN x > 0 THEN y/x > 1.5 ELSE false END;Desain dipaké ku cara kieu
CASEngajaga éksprési tina optimasi, jadi ngan kudu dipake lamun perlu.
# 1: kaayaan pemicu
BEGIN
IF cond(NEW.fld) AND EXISTS(SELECT ...) THEN
...
END IF;
RETURN NEW;
END; Sagalana sigana kasampak alus, tapi ... salah No janji yén investasi SELECT moal dieksekusi lamun kaayaan kahiji palsu. Hayu urang ngalereskeun eta kalawan disarangkeun IF:
BEGIN
IF cond(NEW.fld) THEN
IF EXISTS(SELECT ...) THEN
...
END IF;
END IF;
RETURN NEW;
END; Ayeuna hayu urang tingali taliti - sakabeh awak fungsi pemicu "dibungkus" dina IF. Ieu ngandung harti yén euweuh nyegah urang tina nyoplokkeun kaayaan ieu tina prosedur ngagunakeun :
BEGIN
IF EXISTS(SELECT ...) THEN
...
END IF;
RETURN NEW;
END;
...
CREATE TRIGGER ...
WHEN cond(NEW.fld);Pendekatan ieu dijamin ngahemat sumber daya server nalika kondisina palsu.
# 2: ATAWA / AND ranté
SELECT ... WHERE EXISTS(... A) OR EXISTS(... B) Upami teu kitu, anjeun tiasa mungkas nepi ka duanana EXISTS bakal "leres", tapi duanana bakal kaeusi.
Tapi upami urang terang pasti yén salah sahijina "leres" langkung sering (atanapi "palsu" - pikeun AND-chains) - naha mungkin waé "ningkatkeun prioritasna" supados anu kadua henteu dieksekusi deui?
Tétéla éta mungkin - pendekatan algorithmic deukeut topik artikel .
Hayu urang "nyorong" duanana kaayaan ieu dina CASE:
SELECT ...
WHERE
CASE
WHEN EXISTS(... A) THEN TRUE
WHEN EXISTS(... B) THEN TRUE
END Dina hal ieu kami henteu nangtukeun ELSE-nilai, nyaeta, lamun duanana kaayaan anu palsu CASE bakal mulang NULL, nu diinterpretasi salaku FALSE в WHERE-kaayaan.
Conto ieu tiasa digabungkeun ku cara anu sanés - gumantung kana rasa sareng warna:
SELECT ...
WHERE
CASE
WHEN NOT EXISTS(... A) THEN EXISTS(... B)
ELSE TRUE
END#3: kumaha [teu] nulis kaayaan
Kami nyéépkeun dua dinten pikeun nganalisis alesan pikeun operasi "anéh" tina pemicu ieu - hayu urang tingali naha.
Sumber:
IF( NEW."Документ_" is null or NEW."Документ_" = (select '"Комплект"'::regclass::oid) or NEW."Документ_" = (select to_regclass('"ДокументПоЗарплате"')::oid)
AND ( OLD."ДокументНашаОрганизация" <> NEW."ДокументНашаОрганизация"
OR OLD."Удален" <> NEW."Удален"
OR OLD."Дата" <> NEW."Дата"
OR OLD."Время" <> NEW."Время"
OR OLD."ЛицоСоздал" <> NEW."ЛицоСоздал" ) ) THEN ...Masalah #1: kateusaruaan teu ngahargaan NULL
Hayu urang ngabayangkeun éta sagalana OLD-widang miboga harti NULL. Naon anu bakal kajadian?
SELECT NULL <> 1 OR NULL <> 2;
-- NULL Sareng tina sudut pandang ngerjakeun kaayaan NULL sarua FALSE, sakumaha disebutkeun di luhur.
kaputusan: ngagunakeun operator от ROW-operator, ngabandingkeun sakabéh rékaman sakaligus:
SELECT (NULL, NULL) IS DISTINCT FROM (1, 2);
-- TRUEMasalah #2: palaksanaan anu béda tina fungsi anu sami
Bandingkeun:
NEW."Документ_" = (select '"Комплект"'::regclass::oid)
NEW."Документ_" = (select to_regclass('"ДокументПоЗарплате"')::oid) Naha aya investasi tambahan di dieu? SELECT? Hiji fungsi to_regclass? Naha béda?..
Hayu urang ngalereskeun:
NEW."Документ_" = '"Комплект"'::regclass::oid
NEW."Документ_" = '"ДокументПоЗарплате"'::regclass::oidMasalah #3: prioritas operasi bool
Hayu urang format sumberna:
{... IS NULL} OR
{... Комплект} OR
{... ДокументПоЗарплате} AND
( {... неравенства} ) Aduh... Malah, tétéla lamun salah sahiji dua kaayaan munggaran bener, sakabéh kaayaan robah jadi TRUE, tanpa nyokot kana akun inequalities. Sareng ieu sanés pisan anu urang pikahoyong.
Hayu urang ngalereskeun:
(
{... IS NULL} OR
{... Комплект} OR
{... ДокументПоЗарплате}
) AND
( {... неравенства} )Masalah # 4 (leutik): kompleks ATAWA kaayaan pikeun hiji widang
Sabenerna, urang ngalaman masalah di No 3 persis sabab aya tilu kaayaan. Tapi tinimbang aranjeunna bisa meunang ku hiji, ngagunakeun mékanisme nu coalesce ... IN:
coalesce(NEW."Документ_"::text, '') IN ('', '"Комплект"', '"ДокументПоЗарплате"') Jadi urang NULL "urang gé nyekel", jeung hésé OR Teu kudu dipager ku kurung.
dina total
Hayu urang ngarekam naon anu urang ngagaduhan:
IF (
coalesce(NEW."Документ_"::text, '') IN ('', '"Комплект"', '"ДокументПоЗарплате"') AND
(
OLD."ДокументНашаОрганизация"
, OLD."Удален"
, OLD."Дата"
, OLD."Время"
, OLD."ЛицоСоздал"
) IS DISTINCT FROM (
NEW."ДокументНашаОрганизация"
, NEW."Удален"
, NEW."Дата"
, NEW."Время"
, NEW."ЛицоСоздал"
)
) THEN ... Tur upami Anjeun salah nganggap yén fungsi pemicu ieu ngan bisa dipaké dina UPDATE-pemicu alatan kasadiaan OLD/NEW dina kaayaan tingkat luhur, mangka kaayaan ieu umumna bisa ditempatkeun di WHEN- kaayaan, sakumaha ditémbongkeun dina # 1 ...
sumber: www.habr.com
