SQL C++ เจจเจนเฉเจ เจนเฉ, เจจเจพ เจนเฉ เจเจน JavaScript เจนเฉเฅค เจเจธ เจฒเจ, เจฒเจพเจเจผเฉเจเจฒ เจธเจฎเฉเจเจฐเจจเจพเจ เจฆเจพ เจฎเฉเจฒเจพเจเจเจฃ เจตเฉฑเจเจฐเจพ เจนเฉ, เจ เจคเฉ เจเจน เจฌเจฟเจฒเจเฉเจฒ เจเฉฑเจเฉ เจเฉเจเจผ เจจเจนเฉเจ เจนเฉ:
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
-เจเฉฐเจเฉเจฐเจพเจ) - เจเฉ เจเจฟเจธเฉ เจคเจฐเฉเจนเจพเจ "เจเจธเจฆเฉ เจคเจฐเจเฉเจน เจจเฉเฉฐ เจตเจงเจพเจเจฃเจพ" เจธเฉฐเจญเจต เจนเฉ เจคเจพเจ เจเฉ เจฆเฉเจเฉ เจจเฉเฉฐ เจเฉฑเจ เจตเจพเจฐ เจซเจฟเจฐ เจฒเจพเจเฉ เจจเจพ เจเฉเจคเจพ เจเจพเจตเฉ?
เจเจน เจชเจคเจพ เจเจฒเจฆเจพ เจนเฉ เจเจฟ เจเจน เจธเฉฐเจญเจต เจนเฉ - เจ
เจฒเจเฉเจฐเจฟเจฆเจฎเจฟเจ เจชเจนเฉเฉฐเจ เจฒเฉเจ เจฆเฉ เจตเจฟเจธเจผเฉ เจฆเฉ เจจเฉเฉเฉ เจนเฉ
เจเจ เจเจนเจจเจพเจ เจฆเฉเจนเจพเจ เจธเจผเจฐเจคเจพเจ เจจเฉเฉฐ "เจเฉเจธ เจฆเฉ เจนเฉเจ เจพเจ เจงเฉฑเจเฉ" เจเจฐเฉเจ:
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 เจตเจฟเฉฑเจ เจฆเจฟเจเจพเจเจ เจเจฟเจ เจนเฉ ...
เจธเจฐเฉเจค: www.habr.com