SQL ma aha C++, mana aha JavaScript. Sidaa darteed, qiimeynta tibaaxaha macquulka ah way ka duwan yihiin, tanina maaha wax la mid ah:
WHERE fncondX() AND fncondY()
= fncondX() && fncondY()
Iyadoo la wanaajinayo qorshaha fulinta weydiinta PostgreSQL
Sidaa darteed, haddii aad weli rabto inaad maamusho mudnaanta, waxaad u baahan tahay qaab dhismeed xaaladahan ka dhig kuwo aan sinnayn shardi leh
Xogta iyo la shaqayntooda ayaa saldhig u ah
#0: RTFM
Bilawga
Marka nidaamka qiimeyntu uu muhiim yahay, waxaa lagu hagaajin karaa dhismaha
CASE
. Tusaale ahaan, habkan si looga fogaado kala qaybinta eber jumlad ahaanWHERE
aan la isku halayn karin:SELECT ... WHERE x > 0 AND y/x > 1.5;
Xulasho nabdoon:
SELECT ... WHERE CASE WHEN x > 0 THEN y/x > 1.5 ELSE false END;
Dhismaha la isticmaalay
CASE
waxay ka ilaalisaa muujinta hagaajinta, markaa waa in la isticmaalo oo kaliya marka loo baahdo.
#1: xaalada kicinta
BEGIN
IF cond(NEW.fld) AND EXISTS(SELECT ...) THEN
...
END IF;
RETURN NEW;
END;
Wax walba waxay u muuqdaan inay si fiican u muuqdaan, laakiin ... Qofna ma ballanqaadayo in maalgashadayaasha SELECT
lama fulin doono haddii shuruudda koowaad ay been tahay. Ku hagaaji buul ku yaal IF
:
BEGIN
IF cond(NEW.fld) THEN
IF EXISTS(SELECT ...) THEN
...
END IF;
END IF;
RETURN NEW;
END;
Hadda aan si taxadar leh u eegno - dhammaan jirka oo dhan ee shaqada kicinta ayaa u soo baxday in ay "duubtay" gudaha IF
. Tani waxay ka dhigan tahay in aysan jirin wax naga horjoogsanaya inaan ka saarno xaaladdan habka isticmaalka WHEN
-shuruudaha
BEGIN
IF EXISTS(SELECT ...) THEN
...
END IF;
RETURN NEW;
END;
...
CREATE TRIGGER ...
WHEN cond(NEW.fld);
Habkani wuxuu kuu ogolaanayaa inaad kaydiso agabka serverka oo leh dammaanad haddii xaaladdu been tahay.
#2: AMA/iyo silsilad
SELECT ... WHERE EXISTS(... A) OR EXISTS(... B)
Haddii kale, waxaa la heli karaa in labadaba EXISTS
run noqon doontaa, laakiin labadaba waa la fulin doonaa.
Laakiin haddii aan si hubaal ah u ogaano in mid ka mid ah uu yahay "run" marar badan (ama "been" - waayo AND
-Silsilado) - Suurtagal ma tahay in si uun "loo kordhiyo mudnaanta" si aan kan labaad mar kale loo fulin?
Waxay soo baxday in ay suurtagal tahay - habka algorithmically wuxuu ku dhow yahay mawduuca maqaalka
Aynu kaliya "ku xoorno CASE" labadan xaaladood:
SELECT ...
WHERE
CASE
WHEN EXISTS(... A) THEN TRUE
WHEN EXISTS(... B) THEN TRUE
END
Xaaladdan, ma aynaan qeexin ELSE
-qiimaha, taas oo ah, haddii labada shuruudood ay been yihiin CASE
soo laaban doona NULL
, oo loo fasirtay FALSE
Π² WHERE
- shuruudaha.
Tusaalahan waxaa lagu dari karaa si kale - dhadhan iyo midab:
SELECT ...
WHERE
CASE
WHEN NOT EXISTS(... A) THEN EXISTS(... B)
ELSE TRUE
END
#3: sida [aan] loo qorin shuruudaha
Waxaan ku qaadanay laba maalmood falanqaynta sababaha "wax yaabka leh" ee kicinta kiciyaan - aynu aragno sababta.
Xigasho:
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 ...
Dhibaatada #1: Sinnaan la'aanta kuma xisaabtanto NULL
Aynu ka soo qaadno in wax walba OLD
-beeraha muhiim NULL
. Maxaa dhici doona?
SELECT NULL <> 1 OR NULL <> 2;
-- NULL
Iyo marka laga eego dhinaca ka shaqeynta shuruudaha NULL
u dhiganta FALSE
, sida kor ku xusan.
go'aanka: isticmaal hawlwadeen IS DISTINCT FROM
ROW
- hawlwadeen, isbarbar dhigaya dhammaan diiwaanada hal mar:
SELECT (NULL, NULL) IS DISTINCT FROM (1, 2);
-- TRUE
Dhibaatada lambarka 2: hirgelinta kala duwan ee isla shaqeynta
Isbarbardhig:
NEW."ΠΠΎΠΊΡΠΌΠ΅Π½Ρ_" = (select '"ΠΠΎΠΌΠΏΠ»Π΅ΠΊΡ"'::regclass::oid)
NEW."ΠΠΎΠΊΡΠΌΠ΅Π½Ρ_" = (select to_regclass('"ΠΠΎΠΊΡΠΌΠ΅Π½ΡΠΠΎΠΠ°ΡΠΏΠ»Π°ΡΠ΅"')::oid)
Maxay u jiraan maalgashi dheeri ah SELECT
? Shaqo to_regclass
? Maxay uga duwan tahay...
Aan hagaajino:
NEW."ΠΠΎΠΊΡΠΌΠ΅Π½Ρ_" = '"ΠΠΎΠΌΠΏΠ»Π΅ΠΊΡ"'::regclass::oid
NEW."ΠΠΎΠΊΡΠΌΠ΅Π½Ρ_" = '"ΠΠΎΠΊΡΠΌΠ΅Π½ΡΠΠΎΠΠ°ΡΠΏΠ»Π°ΡΠ΅"'::regclass::oid
Dhibaatada # 3: ka horeynta bool
Aynu qaabaynno isha:
{... IS NULL} OR
{... ΠΠΎΠΌΠΏΠ»Π΅ΠΊΡ} OR
{... ΠΠΎΠΊΡΠΌΠ΅Π½ΡΠΠΎΠΠ°ΡΠΏΠ»Π°ΡΠ΅} AND
( {... Π½Π΅ΡΠ°Π²Π΅Π½ΡΡΠ²Π°} )
Oops ... Dhab ahaantii, waxay soo baxday in kiiska runta mid ka mid ah labada shuruudood ee hore, xaaladda oo dhan waxay isu beddeshaa. TRUE
, iyadoo la tixgelinayo sinnaan la'aanta. Taasna gabi ahaanba ma aha waxaan rabnay.
Aan hagaajino:
(
{... IS NULL} OR
{... ΠΠΎΠΌΠΏΠ»Π΅ΠΊΡ} OR
{... ΠΠΎΠΊΡΠΌΠ΅Π½ΡΠΠΎΠΠ°ΡΠΏΠ»Π°ΡΠ΅}
) AND
( {... Π½Π΅ΡΠ°Π²Π΅Π½ΡΡΠ²Π°} )
Dhibaatada #4 (yar): adag AMA xaalad hal goob
Dhab ahaantii, waxaan dhibaato kala kulanay lambarka 3 si sax ah sababtoo ah waxaa jiray saddex xaaladood. Laakiin halkii iyaga, waxaad ku heli kartaa mid, adoo isticmaalaya habka coalesce ... IN
:
coalesce(NEW."ΠΠΎΠΊΡΠΌΠ΅Π½Ρ_"::text, '') IN ('', '"ΠΠΎΠΌΠΏΠ»Π΅ΠΊΡ"', '"ΠΠΎΠΊΡΠΌΠ΅Π½ΡΠΠΎΠΠ°ΡΠΏΠ»Π°ΡΠ΅"')
Anaguna sidoo kale NULL
"qabso", oo adag OR
Uma baahnid inaad ku buuqdo qawlka.
Wadarta
Aan hagaajino waxa aan helnay:
IF (
coalesce(NEW."ΠΠΎΠΊΡΠΌΠ΅Π½Ρ_"::text, '') IN ('', '"ΠΠΎΠΌΠΏΠ»Π΅ΠΊΡ"', '"ΠΠΎΠΊΡΠΌΠ΅Π½ΡΠΠΎΠΠ°ΡΠΏΠ»Π°ΡΠ΅"') AND
(
OLD."ΠΠΎΠΊΡΠΌΠ΅Π½ΡΠΠ°ΡΠ°ΠΡΠ³Π°Π½ΠΈΠ·Π°ΡΠΈΡ"
, OLD."Π£Π΄Π°Π»Π΅Π½"
, OLD."ΠΠ°ΡΠ°"
, OLD."ΠΡΠ΅ΠΌΡ"
, OLD."ΠΠΈΡΠΎΠ‘ΠΎΠ·Π΄Π°Π»"
) IS DISTINCT FROM (
NEW."ΠΠΎΠΊΡΠΌΠ΅Π½ΡΠΠ°ΡΠ°ΠΡΠ³Π°Π½ΠΈΠ·Π°ΡΠΈΡ"
, NEW."Π£Π΄Π°Π»Π΅Π½"
, NEW."ΠΠ°ΡΠ°"
, NEW."ΠΡΠ΅ΠΌΡ"
, NEW."ΠΠΈΡΠΎΠ‘ΠΎΠ·Π΄Π°Π»"
)
) THEN ...
Oo marka la eego in shaqada kicinta kaliya loo isticmaali karo gudaha UPDATE
kiciya sababtoo ah joogitaanka OLD/NEW
xaalada heerka sare, markaa xaaladan guud ahaan waa la soo saari karaa WHEN
-xaalad sida ku cad #1...
Source: www.habr.com