PostgreSQL Antipatterns: เบเบฒเบ™เบ›เบฐเป€เบกเบตเบ™เป€เบ‡เบทเปˆเบญเบ™เป„เบ‚เปƒเบ™ SQL

SQL เบšเปเปˆเปเบกเปˆเบ™ C ++, เปเบฅเบฐเบšเปเปˆเปเบกเปˆเบ™ JavaScript. เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เบเบฒเบ™เบ„เบดเบ”เป„เบฅเปˆเบเบฒเบ™เบชเบฐเปเบ”เบ‡เบญเบญเบเบขเปˆเบฒเบ‡เบกเบตเป€เบซเบ”เบœเบปเบ™เป€เบเบตเบ”เบ‚เบทเป‰เบ™เปเบ•เบเบ•เปˆเบฒเบ‡เบเบฑเบ™, เปเบฅเบฐเบ™เบตเป‰เบšเปเปˆเปเบกเปˆเบ™เบชเบดเปˆเบ‡เบ”เบฝเบงเบเบฑเบ™เบ—เบฑเบ‡เบซเบกเบปเบ”:

WHERE fncondX() AND fncondY()

= fncondX() && fncondY()

เปƒเบ™เบ‚เบฐเบšเบงเบ™เบเบฒเบ™เป€เบžเบตเปˆเบกเบ›เบฐเบชเบดเบ”เบ—เบดเบžเบฒเบšเปเบœเบ™เบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เบเบฒเบ™เบชเบญเบšเบ–เบฒเบก PostgreSQL เบชเบฒเบกเบฒเบ” "เบˆเบฑเบ”เบฅเบฝเบ‡เบ„เบทเบ™" เป€เบ‡เบทเปˆเบญเบ™เป„เบ‚เบ—เบฝเบšเป€เบ—เบปเปˆเบฒเป„เบ”เป‰เป‚เบ”เบเบ•เบปเบ™เป€เบญเบ‡, เบขเปˆเบฒเบ„เบดเบ”เป„เบฅเปˆเบšเบฒเบ‡เบชเปˆเบงเบ™เบ‚เบญเบ‡เบžเบงเบเป€เบ‚เบปเบฒเบชเปเบฒเบฅเบฑเบšเบšเบฑเบ™เบ—เบถเบเบชเปˆเบงเบ™เบšเบธเบเบ„เบปเบ™, เบเปˆเบฝเบงเบ‚เป‰เบญเบ‡เบเบฑเบšเป€เบ‡เบทเปˆเบญเบ™เป„เบ‚เบ‚เบญเบ‡เบ”เบฑเบ”เบชเบฐเบ™เบตเบ—เบตเปˆเบ™เปเบฒเปƒเบŠเป‰ ... เปƒเบ™เบชเบฑเป‰เบ™, เบงเบดเบ—เบตเบ—เบตเปˆเบ‡เปˆเบฒเบเบ—เบตเปˆเบชเบธเบ”เปเบกเปˆเบ™เบชเบปเบกเบกเบธเบ”เบงเปˆเบฒเบ—เปˆเบฒเบ™. เบšเปเปˆเบชเบฒเบกเบฒเบ”เบ„เบงเบšเบ„เบธเบกเป„เบ”เป‰ เบžเบงเบเป€เบ‚เบปเบฒเบˆเบฐเบขเบนเปˆเปƒเบ™เบฅเปเบฒเบ”เบฑเบšเปƒเบ” (เปเบฅเบฐเบงเปˆเบฒเบžเบงเบเป€เบ‚เบปเบฒเบˆเบฐเบ„เบดเบ”เป„เบฅเปˆเบ—เบฑเบ‡เบซเบกเบปเบ”เบšเป) เป€เบ—เบปเปˆเบฒโ€‹เบ—เบฝเบกโ€‹เบเบฑเบ™ เป€เบ‡เบทเปˆเบญเบ™เป„เบ‚.

เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เบ–เป‰เบฒเบ—เปˆเบฒเบ™เบเบฑเบ‡เบ•เป‰เบญเบ‡เบเบฒเบ™เบˆเบฑเบ”เบเบฒเบ™เบšเบนเบฅเบดเบกเบฐเบชเบดเบ”, เบ—เปˆเบฒเบ™เบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เบชเป‰เบฒเบ‡เป‚เบ„เบ‡เบชเป‰เบฒเบ‡ เป€เบฎเบฑเบ”เปƒเบซเป‰เป€เบ‡เบทเปˆเบญเบ™เป„เบ‚เป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰เบšเปเปˆเป€เบ—เบปเปˆเบฒเบ—เบฝเบกเบเบฑเบ™ เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เป€เบ‡เบทเปˆเบญเบ™เป„เบ‚ เบเบฒเบ™เบชเบฐเปเบ”เบ‡เบญเบญเบ ะธ เบœเบนเป‰เบ›เบฐเบเบญเบšเบเบฒเบ™.

PostgreSQL Antipatterns: เบเบฒเบ™เบ›เบฐเป€เบกเบตเบ™เป€เบ‡เบทเปˆเบญเบ™เป„เบ‚เปƒเบ™ SQL
เบ‚เปเป‰เบกเบนเบ™เปเบฅเบฐเบเบฒเบ™เป€เบฎเบฑเบ”เบงเบฝเบเบเบฑเบšเบžเบงเบเป€เบ‚เบปเบฒเปเบกเปˆเบ™เบžเบทเป‰เบ™เบ–เบฒเบ™ เบชเบฐเบฅเบฑเบšเบชเบฑเบšเบŠเป‰เบญเบ™ VLSI เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เบกเบฑเบ™เป€เบ›เบฑเบ™เบชเบดเปˆเบ‡เบชเปเบฒเบ„เบฑเบ™เบซเบผเบฒเบเบชเปเบฒเบฅเบฑเบšเบžเบงเบเป€เบฎเบปเบฒเบ—เบตเปˆเบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เบ‡เบฒเบ™เบเปˆเบฝเบงเบเบฑเบšเบžเบงเบเบกเบฑเบ™เบšเปเปˆเบžเบฝเบ‡เปเบ•เปˆเบ–เบทเบเบ›เบฐเบ•เบดเบšเบฑเบ”, เปเบ•เปˆเบเบฑเบ‡เบกเบตเบ›เบฐเบชเบดเบ”เบ—เบดเบžเบฒเบš. เปƒเบซเป‰เป€เบšเบดเปˆเบ‡เบ•เบปเบงเบขเปˆเบฒเบ‡เบชเบฐเป€เบžเบฒเบฐเบšเปˆเบญเบ™เบ—เบตเปˆเบ„เบงเบฒเบกเบœเบดเบ”เบžเบฒเบ”เปƒเบ™เบเบฒเบ™เบ„เบดเบ”เป„เบฅเปˆเบเบฒเบ™เบชเบฐเปเบ”เบ‡เบญเบญเบเบชเบฒเบกเบฒเบ”เป€เบฎเบฑเบ”เป„เบ”เป‰, เปเบฅเบฐเบšเปˆเบญเบ™เบ—เบตเปˆเบกเบฑเบ™เบ„เบธเป‰เบกเบ„เปˆเบฒเปƒเบ™เบเบฒเบ™เบ›เบฑเบšเบ›เบธเบ‡เบ›เบฐเบชเบดเบ”เบ—เบดเบžเบฒเบšเบ‚เบญเบ‡เบกเบฑเบ™.

#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: OR/AND เบ•เปˆเบญเบ‡เป‚เบชเป‰

SELECT ... WHERE EXISTS(... A) OR EXISTS(... B)

เบ–เป‰เบฒเบšเปเปˆเบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบชเบดเป‰เบ™เบชเบธเบ”เบ”เป‰เบงเบเบ—เบฑเบ‡เบชเบญเบ‡ EXISTS เบˆเบฐเป€เบ›เบฑเบ™ "เบ„เบงเบฒเบกเบˆเบดเบ‡", เปเบ•เปˆ เบ—เบฑเบ‡เบชเบญเบ‡เบˆเบฐเป„เบ”เป‰เบฎเบฑเบšเบเบฒเบ™เบšเบฑเบ™เบฅเบธเบœเบปเบ™.

เปเบ•เปˆเบ–เป‰เบฒเบžเบงเบเป€เบฎเบปเบฒเบฎเบนเป‰เปเบ™เปˆเบ™เบญเบ™เบงเปˆเบฒเบซเบ™เบถเปˆเบ‡เปƒเบ™เบ™เบฑเป‰เบ™เปเบกเปˆเบ™ "เบ„เบงเบฒเบกเบˆเบดเบ‡" เป€เบฅเบทเป‰เบญเบเป† (เบซเบผเบท "เบœเบดเบ”" - เบชเปเบฒเบฅเบฑเบš AND-chains) - เบกเบฑเบ™เป€เบ›เบฑเบ™เป„เบ›เป„เบ”เป‰เปเบ™เบงเปƒเบ”เบ—เบตเปˆเบˆเบฐ "เป€เบžเบตเปˆเบกเบ„เบงเบฒเบกเบชเปเบฒเบ„เบฑเบ™เบ‚เบญเบ‡เบกเบฑเบ™" เป€เบžเบทเปˆเบญเบงเปˆเบฒเบญเบฑเบ™เบ—เบตเบชเบญเบ‡เบšเปเปˆเป„เบ”เป‰เบ–เบทเบเบ›เบฐเบ•เบดเบšเบฑเบ”เบญเบตเบเป€เบ—เบทเปˆเบญเบซเบ™เบถเปˆเบ‡เบšเป?

เบกเบฑเบ™ turns เปƒเบซเป‰เป€เบซเบฑเบ™เบงเปˆเบฒเบกเบฑเบ™เป€เบ›เบฑเบ™เป„เบ›เป„เบ”เป‰ - เบงเบดเบ—เบตเบเบฒเบ™ algorithmic เปเบกเปˆเบ™เปƒเบเป‰เบŠเบดเบ”เบเบฑเบšเบซเบปเบงเบ‚เปเป‰เบ‚เบญเบ‡เบšเบปเบ”เบ„เบงเบฒเบก PostgreSQL Antipatterns: เบšเบฑเบ™เบ—เบถเบเบ—เบตเปˆเบซเบฒเบเบฒเบเบˆเบฐเป„เบ›เบฎเบญเบ”เบเบฒเบ‡เบ‚เบญเบ‡เบเบฒเบ™เป€เบ‚เบปเป‰เบฒเบฎเปˆเบงเบก.

เปƒเบซเป‰เบžเบฝเบ‡เปเบ•เปˆ "shove" เบ—เบฑเบ‡เบชเบญเบ‡เป€เบ‡เบทเปˆเบญเบ™เป„เบ‚เป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰เบžเบฒเบเปƒเบ•เป‰เบเปเบฅเบฐเบ™เบต:

SELECT ...
WHERE
  CASE
    WHEN EXISTS(... A) THEN TRUE
    WHEN EXISTS(... B) THEN TRUE
  END

เปƒเบ™เบเปเบฅเบฐเบ™เบตเบ”เบฑเปˆเบ‡เบเปˆเบฒเบงเบ™เบตเป‰, เบžเบงเบเป€เบฎเบปเบฒเบšเปเปˆเป„เบ”เป‰เบเปเบฒเบ™เบปเบ” ELSE-value, เบ™เบฑเป‰เบ™เปเบกเปˆเบ™, เบ–เป‰เบฒเป€เบ‡เบทเปˆเบญเบ™เป„เบ‚เบ—เบฑเบ‡เบชเบญเบ‡เปเบกเปˆเบ™เบšเปเปˆเบ–เบทเบเบ•เป‰เบญเบ‡ 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-fields เบกเบตโ€‹เบ„เบงเบฒเบกโ€‹เบซเบกเบฒเบโ€‹ 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: เบšเบนเบฅเบดเบกเบฐเบชเบดเบ”เบ‚เบญเบ‡เบเบฒเบ™เบ”เปเบฒเป€เบ™เบตเบ™เบ‡เบฒเบ™ bool

เบกเบฒเบˆเบฑเบ”เบฎเบนเบšเปเบšเบšเปเบซเบผเปˆเบ‡เบ—เบตเปˆเบกเบฒ:

{... IS NULL} OR
{... ะšะพะผะฟะปะตะบั‚} OR
{... ะ”ะพะบัƒะผะตะฝั‚ะŸะพะ—ะฐั€ะฟะปะฐั‚ะต} AND
( {... ะฝะตั€ะฐะฒะตะฝัั‚ะฒะฐ} )

เป‚เบญเป‰เบ... เปƒเบ™เบ„เบงเบฒเบกเป€เบ›เบฑเบ™เบˆเบดเบ‡, เบกเบฑเบ™เป„เบ”เป‰เบซเบฑเบ™เบญเบญเบเบงเปˆเบฒเบ–เป‰เบฒเบซเบฒเบเบงเปˆเบฒเบซเบ™เบถเปˆเบ‡เปƒเบ™เบชเบญเบ‡เป€เบ‡เบทเปˆเบญเบ™เป„เบ‚เบ—เปเบฒเบญเบดเบ”เป€เบ›เบฑเบ™เบ„เบงเบฒเบกเบˆเบดเบ‡, เบชเบฐเบžเบฒเบšเบ—เบฑเบ‡เบซเบกเบปเบ”เบเบฒเบเป€เบ›เบฑเบ™ TRUE, เป‚เบ”เบเบšเปเปˆเบกเบตเบเบฒเบ™เบ„เปเบฒเบ™เบถเบ‡เป€เบ–เบดเบ‡เบ„เบงเบฒเบกเบšเปเปˆเบชเบฐเป€เบซเบกเบตเบžเบฒเบš. เปเบฅเบฐเบ™เบตเป‰เบšเปเปˆเปเบกเปˆเบ™เบชเบดเปˆเบ‡เบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เบเบฒเบ™.

เปƒเบซเป‰เปเบเป‰เป„เบ‚:

(
  {... IS NULL} OR
  {... ะšะพะผะฟะปะตะบั‚} OR
  {... ะ”ะพะบัƒะผะตะฝั‚ะŸะพะ—ะฐั€ะฟะปะฐั‚ะต}
) AND
( {... ะฝะตั€ะฐะฒะตะฝัั‚ะฒะฐ} )

เบšเบฑเบ™เบซเบฒ #4 (เบ™เป‰เบญเบ): เบŠเบฑเบšเบŠเป‰เบญเบ™ OR เป€เบ‡เบทเปˆเบญเบ™เป„เบ‚เบชเปเบฒเบฅเบฑเบšเบŠเปˆเบญเบ‡เบ‚เปเป‰เบกเบนเบ™เบซเบ™เบถเปˆเบ‡

เบ•เบปเบงเบˆเบดเบ‡เปเบฅเป‰เบง, เบžเบงเบเป€เบฎเบปเบฒเบกเบตเบšเบฑเบ™เบซเบฒเบขเบนเปˆเปƒเบ™เบ‚เปเป‰ 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 ...

เปเบฅเบฐเบ–เป‰เบฒเบ—เปˆเบฒเบ™เบžเบดเบˆเบฒเบฅเบฐเบ™เบฒเบงเปˆเบฒเบŸเบฑเบ‡เบŠเบฑเบ™ trigger เบ™เบตเป‰เบชเบฒเบกเบฒเบ”เปƒเบŠเป‰เป„เบ”เป‰เบžเบฝเบ‡เปเบ•เปˆเปƒเบ™ UPDATE- เบœเบปเบ™โ€‹เบเบฐโ€‹เบ—เบปเบšโ€‹เป€เบ™เบทเปˆเบญเบ‡โ€‹เบˆเบฒเบโ€‹เบกเบตโ€‹ OLD/NEW เบขเบนเปˆเปƒเบ™เบชเบฐเบžเบฒเบšเบฅเบฐเบ”เบฑเบšเป€เบ—เบดเบ‡, เป‚เบ”เบเบ—เบปเปˆเบงเป„เบ›เปเบฅเป‰เบงเบชเบฐเบžเบฒเบšเบเบฒเบ™เบ™เบตเป‰เบชเบฒเบกเบฒเบ”เบ–เบทเบเบงเบฒเบ‡เป„เบงเป‰เปƒเบ™ WHEN- เบชเบฐโ€‹เบžเบฒเบšโ€‹เบเบฒเบ™โ€‹, เบ”เบฑเปˆเบ‡โ€‹เบ—เบตเปˆโ€‹เบชเบฐโ€‹เปเบ”เบ‡โ€‹เปƒเบซเป‰โ€‹เป€เบซเบฑเบ™โ€‹เปƒเบ™ #1 ...

เปเบซเบผเปˆเบ‡เบ‚เปเป‰เบกเบนเบ™: www.habr.com

เป€เบžเบตเปˆเบกเบ„เบงเบฒเบกเบ„เบดเบ”เป€เบซเบฑเบ™