SQL C++ አይደለም፣ ወይም ጃቫስክሪፕት አይደለም። ስለዚህ, የሎጂክ አገላለጾች ግምገማ የተለየ ነው, እና ይህ በጭራሽ አንድ አይነት አይደለም.
WHERE fncondX() AND fncondY()
= fncondX() && fncondY()
የPostgreSQL መጠይቅን የማስፈጸሚያ እቅድ ሲያመቻቹ
ስለዚህ, አሁንም ቅድሚያውን ማስተዳደር ከፈለጉ, መዋቅራዊ መሆን አለብዎት እነዚህ ሁኔታዎች እኩል እንዳይሆኑ ያድርጉ ሁኔታዊ ጋር
መረጃ እና ከእነሱ ጋር አብሮ መስራት መሰረት ነው
#0፡ RTFM
በመጀመር ላይ
የግምገማው ቅደም ተከተል አስፈላጊ በሚሆንበት ጊዜ ከግንባታው ጋር ሊስተካከል ይችላል
CASE
. ለምሳሌ፣ በአረፍተ ነገር ውስጥ በዜሮ መከፋፈልን ለማስወገድ በዚህ መንገድWHERE
የማይታመን፡SELECT ... WHERE x > 0 AND y/x > 1.5;
አስተማማኝ አማራጭ፡-
SELECT ... WHERE CASE WHEN x > 0 THEN y/x > 1.5 ELSE false END;
ጥቅም ላይ የዋለው ግንባታ
CASE
አገላለጹን ከማመቻቸት ይከላከላል, ስለዚህ አስፈላጊ በሚሆንበት ጊዜ ብቻ ጥቅም ላይ መዋል አለበት.
#1: ቀስቅሴ ሁኔታ
BEGIN
IF cond(NEW.fld) AND EXISTS(SELECT ...) THEN
...
END IF;
RETURN NEW;
END;
ሁሉም ነገር ጥሩ ይመስላል, ግን ... ማንም ሰው ኢንቨስት እንዳደረገው ቃል አይገባም SELECT
የመጀመሪያው ሁኔታ ውሸት ከሆነ አይፈፀምም. ጋር አስተካክለው መክተቻ IF
:
BEGIN
IF cond(NEW.fld) THEN
IF EXISTS(SELECT ...) THEN
...
END IF;
END IF;
RETURN NEW;
END;
አሁን በጥንቃቄ እንመልከተው - የመቀስቀሻ ተግባሩ አጠቃላይ አካል ወደ ውስጥ "መጠቅለል" ሆነ IF
. እና ይህ ማለት ይህንን ሁኔታ በመጠቀም ከሂደቱ ውስጥ ምንም ነገር ከማስወገድ የሚከለክለን ነገር የለም ማለት ነው WHEN
- ሁኔታዎች
BEGIN
IF EXISTS(SELECT ...) THEN
...
END IF;
RETURN NEW;
END;
...
CREATE TRIGGER ...
WHEN cond(NEW.fld);
ይህ አካሄድ ሁኔታው የተሳሳተ ከሆነ የአገልጋይ ሃብቶችን ከዋስትና እንዲያስቀምጡ ያስችልዎታል።
#2፡ ወይም/እና ሰንሰለት
SELECT ... WHERE EXISTS(... A) OR EXISTS(... B)
አለበለዚያ ሁለቱንም ማግኘት ይቻላል EXISTS
እውነት ይሆናል, ግን ሁለቱም ይገደላሉ.
ነገር ግን ከመካከላቸው አንዱ ብዙ ጊዜ "እውነት" እንደሆነ በእርግጠኝነት ካወቅን (ወይም "ውሸት" - ለ AND
-ሰንሰለቶች) - ሁለተኛው እንደገና እንዳይፈፀም በሆነ መንገድ "ቅድሚያውን ማሳደግ" ይቻላል?
የሚቻል ሆኖ ተገኝቷል - አልጎሪዝም አቀራረብ ወደ መጣጥፉ ርዕስ ቅርብ ነው።
እነዚህን ሁለቱንም ሁኔታዎች "በCASE ስር" እናንሳ።
SELECT ...
WHERE
CASE
WHEN EXISTS(... A) THEN TRUE
WHEN EXISTS(... B) THEN TRUE
END
በዚህ ጉዳይ ላይ, እኛ አልገለፅንም ELSE
- እሴት, ማለትም, ሁለቱም ሁኔታዎች ውሸት ከሆኑ CASE
ይመለሳል NULL
ተብሎ ይተረጎማል FALSE
в WHERE
- ሁኔታዎች.
ይህ ምሳሌ በሌላ መንገድ ሊጣመር ይችላል - ለመቅመስ እና ለማቅለም:
SELECT ...
WHERE
CASE
WHEN NOT EXISTS(... A) THEN EXISTS(... B)
ELSE TRUE
END
#3: ሁኔታዎችን እንዴት [አይጻፍም]
የዚህን ቀስቅሴ “እንግዳ” መንስዔ ምክንያቶችን በመተንተን ሁለት ቀናትን አሳልፈናል - ለምን እንደሆነ እንይ።
ምንጭ፡-
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 ...
ችግር #1፡ አለመመጣጠን NULLን አያመለክትም።
ሁሉንም ነገር እናስብ OLD
- መስኮች አስፈላጊ ናቸው NULL
. ምን ይሆናል?
SELECT NULL <> 1 OR NULL <> 2;
-- NULL
እና ሁኔታዎችን ከመሥራት አንጻር NULL
ተመጣጣኝ FALSE
, ከላይ እንደተጠቀሰው.
ዉሳኔኦፕሬተርን ተጠቀም IS DISTINCT FROM
ROW
ኦፕሬተር ፣ ሁሉንም መዝገቦች በአንድ ጊዜ በማነፃፀር
SELECT (NULL, NULL) IS DISTINCT FROM (1, 2);
-- TRUE
ችግር ቁጥር 2: ተመሳሳይ ተግባር የተለያዩ ትግበራ
አወዳድር
NEW."Документ_" = (select '"Комплект"'::regclass::oid)
NEW."Документ_" = (select to_regclass('"ДокументПоЗарплате"')::oid)
ለምን ተጨማሪ ኢንቨስትመንቶች አሉ። SELECT
? ተግባር to_regclass
? ለምን ይለያል...
እናስተካክል፡-
NEW."Документ_" = '"Комплект"'::regclass::oid
NEW."Документ_" = '"ДокументПоЗарплате"'::regclass::oid
ችግር #3፡ ቡል ቅድሚያ
ምንጩን እንቅረፅ፡-
{... IS NULL} OR
{... Комплект} OR
{... ДокументПоЗарплате} AND
( {... неравенства} )
ውይ ... በእውነቱ ፣ ከመጀመሪያዎቹ ሁለት ሁኔታዎች ውስጥ የትኛውም እውነት ከሆነ ፣ አጠቃላይ ሁኔታው ወደ ተለወጠ። TRUE
, እኩልነትን ችላ በማለት. እና ይሄ እኛ የምንፈልገው በፍፁም አይደለም።
እናስተካክል፡-
(
{... IS NULL} OR
{... Комплект} OR
{... ДокументПоЗарплате}
) AND
( {... неравенства} )
ችግር #4 (ትንሽ)፡ ለአንድ መስክ ውስብስብ ወይም ሁኔታ
በእውነቱ, በቁጥር 3 ላይ ችግሮች ነበሩብን ምክንያቱም በትክክል ሶስት ሁኔታዎች ነበሩ. ግን በእነሱ ፋንታ ዘዴውን በመጠቀም በአንዱ ማግኘት ይችላሉ። coalesce ... IN
:
coalesce(NEW."Документ_"::text, '') IN ('', '"Комплект"', '"ДокументПоЗарплате"')
እኛም እንዲሁ ነን NULL
"መያዝ", እና ውስብስብ OR
በቅንፍ መወዛገብ የለብዎትም።
ԸՆԴՀԱՆՈՒՐ ԳԻՆ
ያገኘነውን እናስተካክል፡-
IF (
coalesce(NEW."Документ_"::text, '') IN ('', '"Комплект"', '"ДокументПоЗарплате"') AND
(
OLD."ДокументНашаОрганизация"
, OLD."Удален"
, OLD."Дата"
, OLD."Время"
, OLD."ЛицоСоздал"
) IS DISTINCT FROM (
NEW."ДокументНашаОрганизация"
, NEW."Удален"
, NEW."Дата"
, NEW."Время"
, NEW."ЛицоСоздал"
)
) THEN ...
እና ይህ የመቀስቀስ ተግባር ጥቅም ላይ ሊውል የሚችለው በ ውስጥ ብቻ ነው። UPDATE
በመገኘቱ ምክንያት ቀስቅሴ OLD/NEW
በከፍተኛ ደረጃ ሁኔታ, ይህ ሁኔታ በአጠቃላይ ሊወሰድ ይችላል WHEN
- ሁኔታ በ#1 ላይ እንደሚታየው...
ምንጭ: hab.com