SQL mhuwiex C++, u lanqas JavaScript. Għalhekk, l-evalwazzjoni tal-espressjonijiet loġiċi hija differenti, u din mhix l-istess ħaġa:
WHERE fncondX() AND fncondY()
= fncondX() && fncondY()
Filwaqt li jiġi ottimizzat il-pjan ta 'eżekuzzjoni ta' mistoqsija PostgreSQL
Għalhekk, jekk xorta trid timmaniġġja l-prijorità, għandek bżonn strutturalment jagħmlu dawn il-kundizzjonijiet mhux ugwali bil-kondizzjonali
Id-dejta u l-ħidma magħhom hija l-bażi
#0: RTFM
Bidu
Meta l-ordni tal-evalwazzjoni hija importanti, tista 'tiġi ffissata bil-kostruzzjoni
CASE
. Pereżempju, b'dan il-mod tevita d-diviżjoni b'żero f'sentenzaWHERE
mhux affidabbli:SELECT ... WHERE x > 0 AND y/x > 1.5;
Għażla sikura:
SELECT ... WHERE CASE WHEN x > 0 THEN y/x > 1.5 ELSE false END;
Il-kostruzzjoni użata
CASE
tipproteġi l-espressjoni mill-ottimizzazzjoni, għalhekk għandha tintuża biss meta jkun meħtieġ.
#1: kundizzjoni tal-grillu
BEGIN
IF cond(NEW.fld) AND EXISTS(SELECT ...) THEN
...
END IF;
RETURN NEW;
END;
Kollox jidher li jidher tajjeb, imma... Ħadd ma jwiegħed li l-investit SELECT
mhux se jiġi esegwit jekk l-ewwel kundizzjoni tkun falza. Waħħalha ma ibejt IF
:
BEGIN
IF cond(NEW.fld) THEN
IF EXISTS(SELECT ...) THEN
...
END IF;
END IF;
RETURN NEW;
END;
Issa ejja nħarsu bir-reqqa - il-ġisem kollu tal-funzjoni tal-grillu rriżulta li kien "imgeżwer" fih IF
. U dan ifisser li xejn ma jżommna milli tneħħi din il-kundizzjoni mill-proċedura bl-użu WHEN
-kondizzjonijiet
BEGIN
IF EXISTS(SELECT ...) THEN
...
END IF;
RETURN NEW;
END;
...
CREATE TRIGGER ...
WHEN cond(NEW.fld);
Dan l-approċċ jippermettilek li tiffranka r-riżorsi tas-server b'garanzija jekk il-kundizzjoni tkun falza.
#2: JEW/U katina
SELECT ... WHERE EXISTS(... A) OR EXISTS(... B)
Inkella, jista 'jinkiseb li t-tnejn EXISTS
se jkun veru, imma it-tnejn se jiġu esegwiti.
Imma jekk nafu żgur li wieħed minnhom huwa "veru" ħafna aktar spiss (jew "falz" - għal AND
-ktajjen) - huwa possibbli li b'xi mod "iżżid il-prijorità tagħha" sabiex it-tieni waħda ma terġax tiġi esegwita?
Jirriżulta li huwa possibbli - l-approċċ algoritmikament huwa qrib is-suġġett tal-artikolu
Ejja biss "shove under CASE" dawn iż-żewġ kundizzjonijiet:
SELECT ...
WHERE
CASE
WHEN EXISTS(... A) THEN TRUE
WHEN EXISTS(... B) THEN TRUE
END
F'dan il-każ, aħna ma ddefinijniex ELSE
-value, jiġifieri, jekk iż-żewġ kundizzjonijiet huma foloz CASE
se jirritorna NULL
, li hija interpretata bħala FALSE
в WHERE
- kondizzjonijiet.
Dan l-eżempju jista 'jingħaqad b'mod ieħor - għat-togħma u l-kulur:
SELECT ...
WHERE
CASE
WHEN NOT EXISTS(... A) THEN EXISTS(... B)
ELSE TRUE
END
#3: kif [ma] tikteb kundizzjonijiet
Għaddejna jumejn biex janalizzaw ir-raġunijiet għall-iskattar "stramba" ta 'dan il-grillu - ejja naraw għaliex.
Sors:
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 ...
Problema #1: L-inugwaljanza ma tagħtix kont għal NULL
Ejja nassumu li kollox OLD
-oqsma importanti NULL
. X'se jiġri?
SELECT NULL <> 1 OR NULL <> 2;
-- NULL
U mil-lat ta 'ħidma fil-kundizzjonijiet NULL
ekwivalenti FALSE
, kif imsemmi hawn fuq.
deċiżjoni: uża operatur IS DISTINCT FROM
ROW
-operatur, li jqabbel rekords sħaħ f'daqqa:
SELECT (NULL, NULL) IS DISTINCT FROM (1, 2);
-- TRUE
Problema numru 2: implimentazzjoni differenti tal-istess funzjonalità
Qabbel:
NEW."Документ_" = (select '"Комплект"'::regclass::oid)
NEW."Документ_" = (select to_regclass('"ДокументПоЗарплате"')::oid)
Għaliex hemm investimenti żejda SELECT
? Funzjoni to_regclass
? Għaliex hija differenti...
Ejja nirranġaw:
NEW."Документ_" = '"Комплект"'::regclass::oid
NEW."Документ_" = '"ДокументПоЗарплате"'::regclass::oid
Problema #3: preċedenza bool
Ejja nifformattja s-sors:
{... IS NULL} OR
{... Комплект} OR
{... ДокументПоЗарплате} AND
( {... неравенства} )
Oops ... Fil-fatt, irriżulta li fil-każ tal-verità ta 'kwalunkwe waħda mill-ewwel żewġ kundizzjonijiet, il-kundizzjoni kollha tinbidel fi TRUE
, injorati l-inugwaljanzi. U dan mhu xejn dak li ridna.
Ejja nirranġaw:
(
{... IS NULL} OR
{... Комплект} OR
{... ДокументПоЗарплате}
) AND
( {... неравенства} )
Problema #4 (żgħira): kundizzjoni kumplessa JEW għal qasam wieħed
Fil-fatt, kellna problemi fin-Nru 3 proprju għax kien hemm tliet kundizzjonijiet. Iżda minflokhom, tista 'tmur ma' wieħed, billi tuża l-mekkaniżmu coalesce ... IN
:
coalesce(NEW."Документ_"::text, '') IN ('', '"Комплект"', '"ДокументПоЗарплате"')
Hekk aħna NULL
"qabda", u kumplessa OR
M'għandekx għalfejn tħawwad bil-parentesi.
B'kollox
Ejja nirranġaw dak li ksibna:
IF (
coalesce(NEW."Документ_"::text, '') IN ('', '"Комплект"', '"ДокументПоЗарплате"') AND
(
OLD."ДокументНашаОрганизация"
, OLD."Удален"
, OLD."Дата"
, OLD."Время"
, OLD."ЛицоСоздал"
) IS DISTINCT FROM (
NEW."ДокументНашаОрганизация"
, NEW."Удален"
, NEW."Дата"
, NEW."Время"
, NEW."ЛицоСоздал"
)
) THEN ...
U peress li din il-funzjoni grillu tista 'tintuża biss fi UPDATE
trigger minħabba l-preżenza OLD/NEW
fil-kundizzjoni ta 'livell ta' fuq, allura din il-kundizzjoni ġeneralment tista 'titneħħa fi WHEN
-kondizzjoni kif muri f'#1...
Sors: www.habr.com