SQL nuk është C++ dhe as JavaScript. Prandaj, llogaritja e shprehjeve logjike ndodh ndryshe dhe kjo nuk është e njëjtë:
KU fncondX() DHE fncondY()
= fncondX() && fncondY()
Gjatë optimizimit të planit të ekzekutimit të pyetjes PostgreSQL , të mos llogarisë disa prej tyre për regjistra të veçantë, të lidhë me kushtin e indeksit të aplikuar⊠Në përgjithësi, është më e lehtë të supozohet se ju paraprakisht nuk mund të menaxhoni rendin në të cilin do të llogariten (dhe a do të llogariten fare) kushtet e barabarta. Prandaj, nëse dëshironi të menaxhoni prioritetin, është e nevojshme që
të bëni këto kushte jo të barabarta përmes shprehjeve kushtore dhe .

e kompleksit tonë SBIS Fillestar
#0: RTFM
Kur rendi i llogaritjes është i rëndësishëm, ai mund të fiksuar përmes strukturës :
CASE
. PĂ«r shembull, njĂ« mĂ«nyrĂ« pĂ«r tĂ« shmangur pjesĂ«timin me zero nĂ« njĂ« propozimnuk Ă«shtĂ« e besueshme:KUSELECT ... KU x > 0 DHE y/x > 1.5;NjĂ« variant i sigurt:SELECT ... KU RASTI KUR x > 0 ATĂHERĂ y/x > 1.5 PĂRNDYSH E VĂRTETĂ FALSE; END;
Struktura e aplikuar kështumbron shprehjen nga optimizimi, prandaj duhet ta përdorni vetëm kur është e nevojshme.
. PĂ«r shembull, njĂ« mĂ«nyrĂ« pĂ«r tĂ« shmangur pjesĂ«timin me zero nĂ« njĂ« propozimFILLIM NĂSE cond(NEW.fld) DHE EKZISTON(SELECT ...) ATĂHERĂ ... FUND NĂSE; KTHIM NEW; FUND;
#1: ŃŃĐ»ĐŸĐČОД ĐČ ŃŃОггДŃĐ”
TĂ« gjitha duken mirĂ«, por⊠Askush nuk premton se nĂ« nivelin e parĂ« kushti do tĂ« ekzekutohet vetĂ«m kur kushti i parĂ« Ă«shtĂ« i pavĂ«rtetĂ«. Ta pĂ«rmirĂ«sojmĂ« pĂ«rmes SELECT IF tĂ« thelluara FILLIM NĂSE cond(NEW.fld) ATĂHERĂ NĂSE EKZISTON(SELECT ...) ATĂHERĂ ... FUND NĂSE; FUND NĂSE; KTHIM NEW; FUND; Tani le tĂ« shohim me kujdes â e gjithĂ« trupi i funksionit tĂ« trigger-it u ândĂ«rmjetĂ«suaâ nĂ«:
. Dhe kjo do tĂ« thotĂ« se asgjĂ« nuk na pengon ta nxjerrim kĂ«tĂ« kusht nga procedura pĂ«rmes NĂ Tani le tĂ« shohim me kujdes â e gjithĂ« trupi i funksionit tĂ« trigger-it u ândĂ«rmjetĂ«suaâ nĂ«-kushtit :
SELECT ... KU EKZISTON(... A) OSE EKZISTON(... B)Në rastin e pakëndshëm mund të ndodhë që të dy
#2: OR/AND-ŃĐ”ĐżĐŸŃĐșа
do tĂ« jenĂ« "tĂ« vĂ«rteta", por tĂ« dy dhe do tĂ« ekzekutohen EKZISTON Por nĂ«se ne e dimĂ« saktĂ«sisht se njĂ« prej tyre Ă«shtĂ« "tĂ« vĂ«rtetĂ«" shumĂ« mĂ« shpesh (ose "tĂ« pavĂ«rtetat" â pĂ«r tĂ« dy.
tĂ« dy do tĂ« zbatohen DHE-chains) â can't we somehow 'increase its priority' so that the second doesn't execute unnecessarily?
It turns out we can â the algorithmic approach is close to the topic of the article. .
Let's just 'put both of these conditions under CASE':
SELECT ...
WHERE
CASE
WHEN EXISTS(... A) THEN TRUE
WHEN EXISTS(... B) THEN TRUE
END In this case, we haven't defined ELSE-value, meaning in case both conditions are false. . Për shembull, një mënyrë për të shmangur pjesëtimin me zero në një propozim will return NULL, which is interpreted as FALSE në KU-condition.
This example can also be combined differently â to each their own:
SELECT ...
WHERE
CASE
WHEN NOT EXISTS(... A) THEN EXISTS(... B)
ELSE TRUE
END#3: ĐșаĐș [ĐœĐ”] ĐœĐ°ĐŽĐŸ пОŃаŃŃ ŃŃĐ»ĐŸĐČĐžŃ
We spent two days analyzing the reasons for the 'strange' trigger firing â letâs see why.
Source:
IF( NEW."Document_" is null or NEW."Document_" = (select '"Set"'::regclass::oid) or NEW."Document_" = (select to_regclass('"DocumentBySalary"')::oid)
AND ( OLD."DocumentOurOrganization" <> NEW."DocumentOurOrganization"
OR OLD."Deleted" <> NEW."Deleted"
OR OLD."Date" <> NEW."Date"
OR OLD."Time" <> NEW."Time"
OR OLD."CreatedBy" <> NEW."CreatedBy" ) ) THEN ...Problem â1: the inequality doesnât account for NULL
Let's imagine that all OLD-fields had a value NULL. What will happen?
SELECT NULL <> 1 OR NULL <> 2;
-- NULL And from the perspective of condition processing, NULL is equivalent FALSE, as mentioned earlier.
Zgjidhja: use the operator nga ROW-operator, comparing entire records at once:
SELECT (NULL, NULL) IS DISTINCT FROM (1, 2);
-- TRUEProblem â2: different implementations of the same functionality
Letâs compare:
NEW."Document_" = (select '"Set"'::regclass::oid)
NEW."Document_" = (select to_regclass('"DocumentBySalary"')::oid) Why are there unnecessary nested SELECT? Đ ŃŃĐœĐșŃĐžŃ to_regclass? Đ ĐżĐŸ-ŃĐ°Đ·ĐœĐŸĐŒŃ-ŃĐŸ ĐżĐŸŃĐ”ĐŒŃ?..
Let's fix it:
NEW."Document_" = '"Set"'::regclass::oid
NEW."Document_" = '"DocumentBySalary"'::regclass::oidProblem â3: the precedence of bool operations
Letâs format the source:
{... IS NULL} OR
{... Set} OR
{... DocumentBySalary} AND
( {... inequalities} ) Oops⊠In fact, it turned out that if any of the first two conditions is true, the entire condition turns into TRUE, disregarding the inequalities. And thatâs not at all what we wanted.
Let's fix it:
(
{... IS NULL} OR
{... Set} OR
{... DocumentBySalary}
) AND
( {... inequalities} )Problem â4 (small): complex OR condition for a single field
In fact, the problems in â3 arose precisely because there were three conditions. But instead, we could manage with one using the mechanism coalesce ... IN:
coalesce(NEW."Dokumenti_"::text, '') IN ('', '"Kombinim"', '"DokumentiPërPaguara"') Kështu ne edhe NULL «do të kapim», dhe të komplikuar OSE nuk do të duhet të sillemi me paranteza.
Përveç kësaj
Le të konfirmojmë atë që kemi arritur:
Nëse (
coalesce(NEW."Dokumenti_"::text, '') IN ('', '"Kombinim"', '"DokumentiPërPaguara"') DHE
(
OLD."DokumentiOrganizataJonë"
, OLD."Fshirë"
, OLD."Data"
, OLD."Koha"
, OLD."Krijuesi"
) ĂSHTĂ E DALLUAR NGA (
NEW."DokumentiOrganizataJonë"
, NEW."Fshirë"
, NEW."Data"
, NEW."Koha"
, NEW."Krijuesi"
)
) ATĂHERĂ ... Dhe nĂ«se e kemi parasysh qĂ« kjo funksion trigger mund tĂ« aplikojĂ« vetĂ«m nĂ« UPDATE-trigger pĂ«r shkak tĂ« pranisĂ« sĂ« OLD/NEW nĂ« kushtin mĂ« tĂ« lartĂ«, atĂ«herĂ« ky kusht mund tĂ« nxirret nĂ« FILLIM NĂSE EKZISTON(SELECT ...) ATĂHERĂ ... FUND NĂSE; KTHIM NEW; FUND; ... KRIJO TRIGGER ... NĂSE cond(NEW.fld);-kusht, siç u tregua nĂ« #1âŠ
Burimi: habr.com
