PostgreSQL Antipatterns: SQL рдорд╛ рдЕрд╡рд╕реНрдерд╛ рдореВрд▓реНрдпрд╛рдЩреНрдХрди

SQL C++ рд╣реЛрдЗрди, рдЬрд╛рднрд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╣реЛрдЗрдиред рддреНрдпрд╕рдХрд╛рд░рдг, рддрд╛рд░реНрдХрд┐рдХ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рд╣рд░реВрдХреЛ рдЧрдгрдирд╛ рдлрд░рдХ рд░реВрдкрдорд╛ рд╣реБрдиреНрдЫ, рд░ рдпреЛ рд╕рдмреИ рдПрдЙрдЯреИ рдХреБрд░рд╛ рд╣реЛрдЗрди:

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: рд╡рд╛/рд░ рдЪреЗрди

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

рдЕрдиреНрдпрдерд╛, рддрдкрд╛рдИрдВ рджреБрд╡реИ рд╕рдВрдЧ рд╕рдорд╛рдкреНрдд рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ EXISTS "рд╕рддреНрдп" рд╣реБрдиреЗрдЫ, рддрд░ рджреБрд╡реИ рдкреВрд░рд╛ рд╣реБрдиреЗрдЫ.

рддрд░ рдпрджрд┐ рд╣рд╛рдореА рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдкрдорд╛ рдЬрд╛рдиреНрджрдЫреМрдВ рдХрд┐ рддреА рдордзреНрдпреЗ рдПрдХ "рд╕рддреНрдп" рдзреЗрд░реИ рдкрдЯрдХ (рд╡рд╛ "рдЭреВрдЯреЛ" - рдХреЛ рд▓рд╛рдЧреА AND-рдЪреЗрдиреНрд╕) - рдХреЗ рдпреЛ рд╕рдореНрднрд╡ рдЫ "рдпрд╕рдХреЛ рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рдмрдврд╛рдЙрди" рддрд╛рдХрд┐ рджреЛрд╕реНрд░реЛ рдПрдХ рдкрдЯрдХ рдлреЗрд░рд┐ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реБрдБрджреИрди?

рдпреЛ рд╕рдореНрднрд╡ рдЫ рдХрд┐ рдмрд╛рд╣рд┐рд░ рдЬрд╛рдиреНрдЫ - рдПрд▓реНрдЧреЛрд░рд┐рджрдорд┐рдХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд▓реЗрдЦ рдХреЛ рд╡рд┐рд╖рдп рдирдЬрд┐рдХ рдЫ PostgreSQL Antipatterns: рдПрдХ рджреБрд░реНрд▓рдн рд░реЗрдХрд░реНрдб рдПрдХ JOIN рдХреЛ рдмреАрдЪрдорд╛ рдкреБрдЧреНрдиреЗрдЫ.

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: bool рдЕрдкрд░реЗрд╢рдирд╣рд░реВрдХреЛ рдкреНрд░рд╛рдердорд┐рдХрддрд╛

рд╕реНрд░реЛрдд рдврд╛рдБрдЪрд╛ рдЧрд░реМрдВ:

{... 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

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдердкреНрди