Chan e C ++ a th’ ann an SQL, agus chan e JavaScript. Mar sin, tha àireamhachadh abairtean loidsigeach a 'tachairt ann an dòigh eadar-dhealaichte, agus chan eil seo idir an aon rud:
WHERE fncondX() AND fncondY()
= fncondX() && fncondY()
Anns a’ phròiseas airson plana gnìomh ceist PostgreSQL a bharrachadh
Mar sin, ma tha thu fhathast airson prìomhachas a riaghladh, feumaidh tu a structaradh na cumhaichean seo a dhèanamh neo-ionann cleachdadh chumhachan
Tha dàta agus obrachadh còmhla riutha mar bhunait
#0: RTFM
A' tòiseachadh
Nuair a tha òrdugh measaidh cudromach, faodar a ghlacadh a’ cleachdadh an togail
CASE
. Mar eisimpleir, tha seo na dhòigh air sgaradh le neoni a sheachnadh ann an seantansWHERE
neo-earbsach:SELECT ... WHERE x > 0 AND y/x > 1.5;
Roghainn sàbhailte:
SELECT ... WHERE CASE WHEN x > 0 THEN y/x > 1.5 ELSE false END;
Tha an dealbhadh air a chleachdadh san dòigh seo
CASE
a’ dìon an abairt bho optimization, agus mar sin cha bu chòir a chleachdadh ach nuair a bhios feum air.
# 1: suidheachadh brosnachaidh
BEGIN
IF cond(NEW.fld) AND EXISTS(SELECT ...) THEN
...
END IF;
RETURN NEW;
END;
Tha coltas gu bheil a h-uile dad a 'coimhead math, ach ... chan eil duine a' gealltainn gum bi an tasgadh SELECT
cha tèid a chur an gnìomh ma tha a’ chiad chumha meallta. Feuch an cuir sinn ceart e neadachadh IF
:
BEGIN
IF cond(NEW.fld) THEN
IF EXISTS(SELECT ...) THEN
...
END IF;
END IF;
RETURN NEW;
END;
A-nis leig dhuinn coimhead gu faiceallach - tha corp iomlan a’ ghnìomh brosnachaidh air a “fhilleadh a-steach”. IF
. Tha seo a 'ciallachadh nach eil dad a' cur bacadh oirnn bho bhith a 'toirt air falbh a' chumha seo bhon mhodh-obrachaidh WHEN
- suidheachaidhean
BEGIN
IF EXISTS(SELECT ...) THEN
...
END IF;
RETURN NEW;
END;
...
CREATE TRIGGER ...
WHEN cond(NEW.fld);
Tha an dòigh-obrach seo cinnteach gun sàbhail e goireasan frithealaiche nuair a tha an suidheachadh ceàrr.
#2: NO/AND slabhraidh
SELECT ... WHERE EXISTS(... A) OR EXISTS(... B)
Mur eil, faodaidh tu crìoch a chur air an dà chuid EXISTS
bidh “fìor”, ach bithidh an dà chuid air an coimhlionadh.
Ach ma tha fios againn le cinnt gu bheil aon dhiubh "fìor" mòran nas trice (no "meallta" - airson AND
-chains) - a bheil e comasach dòigh air choireigin “a phrìomhachas àrdachadh” gus nach tèid an dàrna fear a chuir gu bàs a-rithist?
Tha e a 'tionndadh a-mach gu bheil e comasach - an algorithmic dòigh-obrach a tha faisg air a' chuspair an artaigil
Nach dèan sinn ach “gluasad” an dà chuid de na cumhaichean sin fo CASE:
SELECT ...
WHERE
CASE
WHEN EXISTS(... A) THEN TRUE
WHEN EXISTS(... B) THEN TRUE
END
Anns a 'chùis seo cha do rinn sinn mìneachadh ELSE
-luach, is e sin, ma tha an dà shuidheachadh ceàrr CASE
tillidh NULL
, a tha air a mhìneachadh mar FALSE
в WHERE
- suidheachaidhean.
Faodar an eisimpleir seo a chur còmhla ann an dòighean eile - a rèir blas agus dath:
SELECT ...
WHERE
CASE
WHEN NOT EXISTS(... A) THEN EXISTS(... B)
ELSE TRUE
END
#3: ciamar [gun] sgrìobhadh cumhachan
Chuir sinn seachad dà latha a’ dèanamh anailis air na h-adhbharan airson gnìomhachd “neònach” an inneal brosnachaidh seo - chì sinn carson.
Stòr:
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 ...
Duilgheadas #1: chan eil neo-ionannachd a' toirt spèis do NULL
Smaoinichidh sinn gu bheil a h-uile dad OLD
- bha ciall aig raointean NULL
. Dè thachras?
SELECT NULL <> 1 OR NULL <> 2;
-- NULL
Agus bho thaobh obrachadh a-mach nan suidheachaidhean NULL
co-ionann FALSE
, mar a chaidh ainmeachadh gu h-àrd.
co-dhùnadh: cleachd gnìomhaiche IS DISTINCT FROM
ROW
-operator, a 'dèanamh coimeas eadar clàran slàn aig an aon àm:
SELECT (NULL, NULL) IS DISTINCT FROM (1, 2);
-- TRUE
Duilgheadas #2: cur an gnìomh eadar-dhealaichte den aon ghnìomhachd
Dèan coimeas:
NEW."Документ_" = (select '"Комплект"'::regclass::oid)
NEW."Документ_" = (select to_regclass('"ДокументПоЗарплате"')::oid)
Carson a tha tasgadh a bharrachd an seo? SELECT
? A gnìomh to_regclass
? Carson a tha e eadar-dhealaichte? ..
Dèanamaid rèiteachadh:
NEW."Документ_" = '"Комплект"'::regclass::oid
NEW."Документ_" = '"ДокументПоЗарплате"'::regclass::oid
Duilgheadas #3: prìomhachas gnìomhachd bool
Feuch an cuir sinn cruth air an stòr:
{... IS NULL} OR
{... Комплект} OR
{... ДокументПоЗарплате} AND
( {... неравенства} )
Oops... Gu dearbh, thionndaidh e a-mach ma tha gin den chiad dà shuidheachadh fìor, gun tionndaidh an suidheachadh gu lèir gu bhith na TRUE
, gun a bhith a’ toirt aire do neo-ionannachdan. Agus chan e seo idir a bha sinn ag iarraidh.
Dèanamaid rèiteachadh:
(
{... IS NULL} OR
{... Комплект} OR
{... ДокументПоЗарплате}
) AND
( {... неравенства} )
Duilgheadas #4 (beag): suidheachadh iom-fhillte NO airson aon raon
Gu fìrinneach, bha duilgheadasan againn ann an Àir. 3 dìreach leis gu robh trì cumhaichean ann. Ach an àite sin gheibh thu le aon, a 'cleachdadh an uidheamachd coalesce ... IN
:
coalesce(NEW."Документ_"::text, '') IN ('', '"Комплект"', '"ДокументПоЗарплате"')
Mar sin sinn NULL
“Glacaidh sinn”, agus duilich OR
Chan eil feum air feansadh le camagan.
Iomlan
Nach clàraich sinn na fhuair sinn:
IF (
coalesce(NEW."Документ_"::text, '') IN ('', '"Комплект"', '"ДокументПоЗарплате"') AND
(
OLD."ДокументНашаОрганизация"
, OLD."Удален"
, OLD."Дата"
, OLD."Время"
, OLD."ЛицоСоздал"
) IS DISTINCT FROM (
NEW."ДокументНашаОрганизация"
, NEW."Удален"
, NEW."Дата"
, NEW."Время"
, NEW."ЛицоСоздал"
)
) THEN ...
Agus ma tha thu den bheachd nach urrainnear an gnìomh brosnachaidh seo a chleachdadh ach ann an UPDATE
-trigger air sgàth ruigsinneachd OLD/NEW
ann an staid àrd-ìre, mar as trice faodar an suidheachadh seo a chuir a-steach WHEN
-suidheachadh, mar a chithear ann an # 1 ...
Source: www.habr.com