SQL nav C++ un nav JavaScript. TÄdÄļ loÄ£isko izteiksmju novÄrtÄÅ”ana notiek citÄdi, un tas - pavisam nav viens un tas pats:
WHERE fncondX() AND fncondY()
= fncondX() && fncondY()
OptimizÄjot PostgreSQL izpildes plÄna procesus , neizvÄrtÄjot dažus no tiem atseviŔķÄm ierakstiem, pieŔķirot tos pie pielietotÄ indeksa nosacÄ«juma... ÄŖsÄk sakot, visvieglÄk ir uzskatÄ«t, ka jÅ«s iepriekÅ” nevarat kontrolÄt kÄdÄ secÄ«bÄ tiks (un tiks) novÄrtÄti vienlÄ«dzÄ«gi nosacÄ«jumi.
TÄdÄļ, ja prioritÄtes pÄrvaldīŔana tomÄr ir vÄlama, jÄstrukturÄ Å”os nosacÄ«jumus par nevienlÄ«dzÄ«giem izmantojot nosacÄ«jumus un .

Dati un darbs ar tiem ir pamats , tÄdÄļ mums ir ļoti svarÄ«gi, lai operÄcijas ar tiem tiktu veiktas ne tikai pareizi, bet arÄ« efektÄ«vi. ApskatÄ«sim konkrÄtus piemÄrus, kur var rasties kļūdas izteiksmju aprÄÄ·inÄÅ”anÄ, un kur var uzlabot to efektivitÄti.
#0: RTFM
SÄkuma :
Kad aprÄÄ·ina secÄ«ba ir svarÄ«ga, to var nostiprinÄt, izmantojot konstrukciju
CASE. PiemÄram, Å”is veids, kÄ izvairÄ«ties no dalīŔanas ar nulli apgalvojumÄWHEREnav droÅ”s:SELECT ... WHERE x > 0 AND y/x > 1.5;DroÅ”a iespÄja:
SELECT ... WHERE CASE WHEN x > 0 THEN y/x > 1.5 ELSE false END;TÄda konstrukcija
CASEaizsargÄ izteiksmi no optimizÄcijas, tÄdÄļ to vajadzÄtu izmantot tikai tad, kad tas ir nepiecieÅ”ams.
#1: ŃŃŠ»Š¾Š²ŠøŠµ в ŃŃŠøŠ³Š³ŠµŃе
BEGIN
IF cond(NEW.fld) AND EXISTS(SELECT ...) THEN
...
END IF;
RETURN NEW;
END; Viss izskatÄs labi, bet⦠Neviens nenodroÅ”ina, ka iemiesotais SELECT netiks izpildÄ«ts, ja pirmais nosacÄ«jums ir nepaties. Labosim to, izmantojot iekļautus IF:
BEGIN
IF cond(NEW.fld) THEN
IF EXISTS(SELECT ...) THEN
...
END IF;
END IF;
RETURN NEW;
END; Tagad apskatÄ«sim rÅ«pÄ«gi - visa trigeri funkcijas Ä·ermenis izrÄdÄ«jÄs "iesaiÅots" IF. Un tas nozÄ«mÄ, ka nekas neliedz mums izÅemt Å”o nosacÄ«jumu no procedÅ«ras, izmantojot :
BEGIN
IF EXISTS(SELECT ...) THEN
...
END IF;
RETURN NEW;
END;
...
CREATE TRIGGER ...
WHEN cond(NEW.fld);Å Äda pieeja garantÄti ļauj ietaupÄ«t servera resursus, ja nosacÄ«jums ir nepaties.
#2: OR/AND-ŃŠµŠæŠ¾Ńка
SELECT ... WHERE EXISTS(... A) OR EXISTS(... B) NepatÄ«kamÄ gadÄ«jumÄ var bÅ«t tÄ, ka abi EXISTS bÅ«s "patiesi", bet abi tiks izpildÄ«ti.
Bet, ja mÄs precÄ«zi zinÄm, ka viens no tiem ir "paties" daudz biežÄk (vai "nepaties" - attiecÄ«bÄ uz AND-ces afÄnu) ā vai nevarÄtu kaut kÄ Ā«paaugstinÄt tÄ prioritÄtiĀ», lai otrais neizpildÄ«tos lieki?
IzrÄdÄs, var ā algoritmiskais pieejas veids ir lÄ«dzÄ«gs raksta tÄmai .
VienkÄrÅ”i Ā«ieslÄ«dÄsim zem CASEĀ» abos Å”ajos apstÄkļos:
SELECT ...
WHERE
CASE
WHEN EXISTS(... A) THEN TRUE
WHEN EXISTS(... B) THEN TRUE
END Å ajÄ gadÄ«jumÄ mÄs neesam definÄjuÅ”i ELSE-vÄrtÄ«bu, proti, ja abi apstÄkļi ir nepatiesi CASE atgriezÄ«s NULL, kas interpretÄjas kÄ FALSE par WHERE-apstÄkļos.
Å o piemÄru var apvienot arÄ« citÄdi ā pÄc gaumes un krÄsas:
SELECT ...
WHERE
CASE
WHEN NOT EXISTS(... A) THEN EXISTS(... B)
ELSE TRUE
END#3: как [не] наГо ŠæŠøŃŠ°ŃŃ ŃŃŠ»Š¾Š²ŠøŃ
MÄs pavadÄ«jÄm divas dienas, analizÄjot iemeslus Ā«dÄ«vainajaiĀ» Ŕī trigera darbÄ«bai ā apskatÄ«sim, kÄpÄc.
Source code:
IF( NEW."Dokuments_" ir null vai NEW."Dokuments_" = (select '"Komplekts"'::regclass::oid) vai NEW."Dokuments_" = (select to_regclass('"DokumentsPÄrzinÄ"')::oid)
AND ( OLD."DokumentsMÅ«suOrganizÄcija" NEW."DokumentsMÅ«suOrganizÄcija"
OR OLD."DzÄsts" NEW."DzÄsts"
OR OLD."Datums" NEW."Datums"
OR OLD."Laiks" NEW."Laiks"
OR OLD."PersonaIzveidoja" NEW."PersonaIzveidoja" ) ) THEN ...ProblÄma Nr. 1: nevienlÄ«dzÄ«ba neÅem vÄrÄ NULL
IedomÄjieties, ka visi OLD-lauki bija ar vÄrtÄ«bu NULL. Kas sanÄks?
SELECT NULL 1 OR NULL 2;
-- NULL Un no nosacÄ«juma izpildes viedokļa NULL ir ekvivalentÄ FALSE, kÄ minÄts iepriekÅ”.
RisinÄjums: izmantojiet operatoru no ROW-operatora, salÄ«dzinot uzreiz visu ierakstu:
SELECT (NULL, NULL) IS DISTINCT FROM (1, 2);
-- TRUEProblÄma Nr. 2: atŔķirÄ«gs vienÄda funkcionalitÄte Ä«stenojums
SalÄ«dzinÄsim:
NEW."Dokuments_" = (select '"Komplekts"'::regclass::oid)
NEW."Dokuments_" = (select to_regclass('"DokumentsPÄrzinÄ"')::oid) KÄpÄc te lieki iedziļinÄjumi SELECT? Š ŃŃŠ½ŠŗŃŠøŃ to_regclass? Рпо-ŃŠ°Š·Š½Š¾Š¼Ń-ŃŠ¾ ŠæŠ¾ŃŠµŠ¼Ń?..
Labosim:
NEW."Dokuments_" = '"Komplekts"'::regclass::oid
NEW."Dokuments_" = '"DokumentsPÄrzinÄ"'::regclass::oidProblÄma Nr. 3: bool operatoru prioritÄte
FormatÄsim avota kodu:
{... IS NULL} OR
{... Komplekts} OR
{... DokumentsPÄrzinÄ} AND
( {... nevienlÄ«dzÄ«bas} ) Ups⦠Faktiski, izrÄdÄ«jÄs, ka, ja kÄda no pirmajiem diviem nosacÄ«jumiem bÅ«s patiesa, visi nosacÄ«jumi kopumÄ pÄrvÄrÅ”as par TRUE, neraugoties uz nevienlÄ«dzÄ«bÄm. Bet tas vispÄr nav tas, ko vÄlÄjÄmies.
Labosim:
(
{... IS NULL} OR
{... Komplekts} OR
{... DokumentsPÄrzinÄ}
) AND
( {... nevienlÄ«dzÄ«bas} )ProblÄma Nr. 4 (mazs): sarežģīts OR nosacÄ«jums vienam laukam
PatiesÄ«bÄ, problÄmas 3. numurÄ radÄs tieÅ”i tÄpÄc, ka bija trÄ«s nosacÄ«jumi. Bet to vietÄ var iztikt ar vienu, izmantojot mehÄnismu coalesce ... IN:
coalesce(NEW."Dokuments_"::text, '') IN ('', '"Komplekts"', '"DokumentsParAlgu"') TÄ mÄs arÄ« NULL Ā«noÄ·ersimĀ», un sarežģītu OR ar iekavÄm nebÅ«s jÄnodarbojas.
KopÄjÄ summa
FiksÄsim to, ko esam ieguvuÅ”i:
IF (
coalesce(NEW."Dokuments_"::text, '') IN ('', '"Komplekts"', '"DokumentsParAlgu"') AND
(
OLD."DokumentsMÅ«suOrganizÄcija"
, OLD."DzÄsts"
, OLD."Datums"
, OLD."Laiks"
, OLD."PersonasIzveidojis"
) IS DISTINCT FROM (
NEW."DokumentsMÅ«suOrganizÄcija"
, NEW."DzÄsts"
, NEW."Datums"
, NEW."Laiks"
, NEW."PersonasIzveidojis"
)
) THEN ... Un, ja Åem vÄrÄ, ka Å”o trigera funkciju var pielietot tikai UPDATE-trigerÄ«, Åemot vÄrÄ OLD/NEW augstÄ lÄ«meÅa nosacÄ«jumÄ, tad Å”o nosacÄ«jumu var vispÄr iznest WHEN-nosacÄ«jumÄ, kÄ tika parÄdÄ«ts #1ā¦
Avots: habr.com
