<?xml version="1.0" encoding="utf-8" ?>

<rss version="2.0" 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/"
   xmlns:content="http://purl.org/rss/1.0/modules/content/"
   >
<channel>
    <title>Frank Seitz - Developer Logbuch - Datenbank/RDBMS</title>
    <link>http://fseitz.de/blog/</link>
    <description>Notizen aus der Welt der Web-, Datenbank- und Unix-Programmierung</description>
    <dc:language>de</dc:language>
    <generator>Serendipity 1.5.1 - http://www.s9y.org/</generator>
    <pubDate>Tue, 27 Mar 2012 13:18:06 GMT</pubDate>

    <image>
        <url>http://fseitz.de/blog/templates/default/img/s9y_banner_small.png</url>
        <title>RSS: Frank Seitz - Developer Logbuch - Datenbank/RDBMS - Notizen aus der Welt der Web-, Datenbank- und Unix-Programmierung</title>
        <link>http://fseitz.de/blog/</link>
        <width>100</width>
        <height>21</height>
    </image>

<item>
    <title>Lookup-Trigger für Oracle und PostgreSQL</title>
    <link>http://fseitz.de/blog/index.php?/archives/85-Lookup-Trigger-fuer-Oracle-und-PostgreSQL.html</link>
            <category>Datenbank/RDBMS</category>
    
    <comments>http://fseitz.de/blog/index.php?/archives/85-Lookup-Trigger-fuer-Oracle-und-PostgreSQL.html#comments</comments>
    <wfw:comment>http://fseitz.de/blog/wfwcomment.php?cid=85</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://fseitz.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=85</wfw:commentRss>
    

    <author>nospam@example.com (Frank Seitz)</author>
    <content:encoded>
    &lt;p class=&quot;sdoc-para-p&quot;&gt;
  Gegeben ist eine Tabelle &lt;tt class=&quot;sdoc-seg-c&quot;&gt;&amp;lt;table&amp;gt;&lt;/tt&gt; mit einer Kolumne &lt;tt class=&quot;sdoc-seg-c&quot;&gt;&amp;lt;x&amp;gt;&lt;/tt&gt;, deren
  Wert frei manipuliert werden kann, und einer Kolumne &lt;tt class=&quot;sdoc-seg-c&quot;&gt;&amp;lt;y&amp;gt;&lt;/tt&gt;, deren
  Wert funktional von &lt;tt class=&quot;sdoc-seg-c&quot;&gt;&amp;lt;x&amp;gt;&lt;/tt&gt; abhängt (also nicht frei manipuliert werden
  kann). Die Abbildung von &lt;tt class=&quot;sdoc-seg-c&quot;&gt;&amp;lt;x&amp;gt;&lt;/tt&gt; auf &lt;tt class=&quot;sdoc-seg-c&quot;&gt;&amp;lt;y&amp;gt;&lt;/tt&gt; ist in einer Lookup-Tabelle
  &lt;tt class=&quot;sdoc-seg-c&quot;&gt;&amp;lt;lookup_table&amp;gt;&lt;/tt&gt; definiert, die jedem Wert &lt;tt class=&quot;sdoc-seg-c&quot;&gt;&amp;lt;x&amp;gt;&lt;/tt&gt; den
  entsprechenden Wert &lt;tt class=&quot;sdoc-seg-c&quot;&gt;&amp;lt;y&amp;gt;&lt;/tt&gt; zuordnet.
&lt;/p&gt;
&lt;p class=&quot;sdoc-para-p&quot;&gt;
  Aufgabe: Der &lt;tt class=&quot;sdoc-seg-c&quot;&gt;&amp;lt;y&amp;gt;&lt;/tt&gt;-Wert soll in &lt;tt class=&quot;sdoc-seg-c&quot;&gt;&amp;lt;table&amp;gt;&lt;/tt&gt; gespeichert werden und
  stets konstitent zu &lt;tt class=&quot;sdoc-seg-c&quot;&gt;&amp;lt;x&amp;gt;&lt;/tt&gt; sein. Der Wert von &lt;tt class=&quot;sdoc-seg-c&quot;&gt;&amp;lt;y&amp;gt;&lt;/tt&gt; soll &lt;i class=&quot;sdoc-seg-i&quot;&gt;nicht&lt;/i&gt;
  erst bei Abfrage ermittelt werden. Im Prinzip ist das eine unerwüschte
  Redundanz, die aber aus praktischen Gründen sinnvoll sein kann.
&lt;/p&gt;
&lt;p class=&quot;sdoc-para-p&quot;&gt;
  Die Anforderung lässt sich durch einen &lt;tt class=&quot;sdoc-seg-c&quot;&gt;BEFORE INSERT OR
  UPDATE&lt;/tt&gt;-Trigger erfüllen, der beim Einfügen oder Ändern in &lt;tt class=&quot;sdoc-seg-c&quot;&gt;&amp;lt;table&amp;gt;&lt;/tt&gt;
  den &lt;tt class=&quot;sdoc-seg-c&quot;&gt;&amp;lt;y&amp;gt;&lt;/tt&gt;-Wert via &lt;tt class=&quot;sdoc-seg-c&quot;&gt;&amp;lt;x&amp;gt;&lt;/tt&gt; in &lt;tt class=&quot;sdoc-seg-c&quot;&gt;&amp;lt;lookup_table&amp;gt;&lt;/tt&gt; ermittelt und auf
  &lt;tt class=&quot;sdoc-seg-c&quot;&gt;&amp;lt;table&amp;gt;.&amp;lt;y&amp;gt;&lt;/tt&gt; überträgt.
&lt;/p&gt;
&lt;p class=&quot;sdoc-para-p&quot;&gt;
  Es folgt die Lösung für Oracle und PostgreSQL.
&lt;/p&gt;
&lt;h1 class=&quot;sdoc-sec-h1&quot;&gt;Oracle&lt;/h1&gt;
&lt;div class=&quot;sdoc-code-div&quot;&gt;
  &lt;pre class=&quot;sdoc-code-pre&quot;&gt;&lt;span class=&quot;sdoc-code-ln&quot;&gt; 1&lt;/span&gt; &lt;span class=&quot;hl kwa&quot;&gt;CREATE OR REPLACE TRIGGER&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;&amp;lt;&lt;/span&gt;tigger&lt;span class=&quot;hl opt&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hl kwa&quot;&gt;BEFORE INSERT OR UPDATE&lt;/span&gt;&amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt; 2&lt;/span&gt;     &lt;span class=&quot;hl kwa&quot;&gt;ON&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hl kwa&quot;&gt;FOR EACH ROW&lt;/span&gt;&amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt; 3&lt;/span&gt; &lt;span class=&quot;hl kwa&quot;&gt;BEGIN&lt;/span&gt;&amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt; 4&lt;/span&gt;     &lt;span class=&quot;hl kwa&quot;&gt;SELECT&lt;/span&gt;&amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt; 5&lt;/span&gt;         &lt;span class=&quot;hl opt&quot;&gt;&amp;lt;&lt;/span&gt;y&lt;span class=&quot;hl opt&quot;&gt;&amp;gt;&lt;/span&gt;&amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt; 6&lt;/span&gt;     &lt;span class=&quot;hl kwa&quot;&gt;INTO&lt;/span&gt;&amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt; 7&lt;/span&gt;         &lt;span class=&quot;hl kwc&quot;&gt;:new&lt;/span&gt;.&lt;span class=&quot;hl opt&quot;&gt;&amp;lt;&lt;/span&gt;y&lt;span class=&quot;hl opt&quot;&gt;&amp;gt;&lt;/span&gt;&amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt; 8&lt;/span&gt;     &lt;span class=&quot;hl kwa&quot;&gt;FROM&lt;/span&gt;&amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt; 9&lt;/span&gt;         &lt;span class=&quot;hl opt&quot;&gt;&amp;lt;&lt;/span&gt;lookup_table&lt;span class=&quot;hl opt&quot;&gt;&amp;gt;&lt;/span&gt;&amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt;10&lt;/span&gt;     &lt;span class=&quot;hl kwa&quot;&gt;WHERE&lt;/span&gt;&amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt;11&lt;/span&gt;         &lt;span class=&quot;hl opt&quot;&gt;&amp;lt;&lt;/span&gt;x&lt;span class=&quot;hl opt&quot;&gt;&amp;gt; =&lt;/span&gt; &lt;span class=&quot;hl kwc&quot;&gt;:new&lt;/span&gt;.&lt;span class=&quot;hl opt&quot;&gt;&amp;lt;&lt;/span&gt;x&lt;span class=&quot;hl opt&quot;&gt;&amp;gt;;&lt;/span&gt;&amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;hl kwa&quot;&gt;END&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;;&lt;/span&gt;&amp;#10;&lt;/pre&gt;
&lt;/div&gt;
&lt;h1 class=&quot;sdoc-sec-h1&quot;&gt;PostgreSQL&lt;/h1&gt;
&lt;div class=&quot;sdoc-code-div&quot;&gt;
  &lt;pre class=&quot;sdoc-code-pre&quot;&gt;&lt;span class=&quot;sdoc-code-ln&quot;&gt; 1&lt;/span&gt; &lt;span class=&quot;hl kwa&quot;&gt;CREATE FUNCTION&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;&amp;lt;&lt;/span&gt;trigger_func&lt;span class=&quot;hl opt&quot;&gt;&amp;gt;()&lt;/span&gt; &lt;span class=&quot;hl kwa&quot;&gt;RETURNS trigger AS&lt;/span&gt; $$&amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt; 2&lt;/span&gt; &lt;span class=&quot;hl kwa&quot;&gt;BEGIN&lt;/span&gt;&amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt; 3&lt;/span&gt;     &lt;span class=&quot;hl kwa&quot;&gt;SELECT&lt;/span&gt;&amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt; 4&lt;/span&gt;         &lt;span class=&quot;hl opt&quot;&gt;&amp;lt;&lt;/span&gt;y&lt;span class=&quot;hl opt&quot;&gt;&amp;gt;&lt;/span&gt;&amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt; 5&lt;/span&gt;     &lt;span class=&quot;hl kwa&quot;&gt;INTO STRICT&lt;/span&gt;&amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt; 6&lt;/span&gt;         &lt;span class=&quot;hl kwa&quot;&gt;NEW&lt;/span&gt;.&lt;span class=&quot;hl opt&quot;&gt;&amp;lt;&lt;/span&gt;y&lt;span class=&quot;hl opt&quot;&gt;&amp;gt;&lt;/span&gt;&amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt; 7&lt;/span&gt;     &lt;span class=&quot;hl kwa&quot;&gt;FROM&lt;/span&gt;&amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt; 8&lt;/span&gt;         &lt;span class=&quot;hl opt&quot;&gt;&amp;lt;&lt;/span&gt;lookup_table&lt;span class=&quot;hl opt&quot;&gt;&amp;gt;&lt;/span&gt;&amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt; 9&lt;/span&gt;     &lt;span class=&quot;hl kwa&quot;&gt;WHERE&lt;/span&gt;&amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt;10&lt;/span&gt;         &lt;span class=&quot;hl opt&quot;&gt;&amp;lt;&lt;/span&gt;x&lt;span class=&quot;hl opt&quot;&gt;&amp;gt; =&lt;/span&gt; &lt;span class=&quot;hl kwa&quot;&gt;NEW&lt;/span&gt;.&lt;span class=&quot;hl opt&quot;&gt;&amp;lt;&lt;/span&gt;x&lt;span class=&quot;hl opt&quot;&gt;&amp;gt;;&lt;/span&gt;&amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt;11&lt;/span&gt; &amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt;12&lt;/span&gt;     &lt;span class=&quot;hl kwa&quot;&gt;RETURN NEW&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;;&lt;/span&gt;&amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;hl kwa&quot;&gt;END&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;;&lt;/span&gt;&amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt;14&lt;/span&gt; $$ &lt;span class=&quot;hl kwa&quot;&gt;LANGUAGE&lt;/span&gt; plpgsql&lt;span class=&quot;hl opt&quot;&gt;;&lt;/span&gt;&amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt;15&lt;/span&gt; &amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;hl kwa&quot;&gt;CREATE TRIGGER&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hl kwa&quot;&gt;BEFORE INSERT OR UPDATE&lt;/span&gt;&amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt;17&lt;/span&gt;     &lt;span class=&quot;hl kwa&quot;&gt;ON&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hl kwa&quot;&gt;FOR EACH ROW&lt;/span&gt;&amp;#10;&lt;span class=&quot;sdoc-code-ln&quot;&gt;18&lt;/span&gt;     &lt;span class=&quot;hl kwa&quot;&gt;EXECUTE PROCEDURE&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;&amp;lt;&lt;/span&gt;trigger_func&lt;span class=&quot;hl opt&quot;&gt;&amp;gt;();&lt;/span&gt;&amp;#10;&lt;/pre&gt;
&lt;/div&gt;
&lt;p class=&quot;sdoc-para-p&quot;&gt;
  Der Code ist bei beiden Datenbanksystemen ähnlich, die Unterschiede sind im
  Wesentlichen:
&lt;/p&gt;
&lt;ul class=&quot;sdoc-list-ul&quot;&gt;
  &lt;li class=&quot;sdoc-list-li-point&quot; style=&quot;list-style-type:disc&quot;&gt;
    &lt;p class=&quot;sdoc-para-p&quot;&gt;
      Die Prozedur kann bei Oracle als Teil des Triggers definiert werden, was
      den Code einfach und elegant macht. Bei PostgreSQL ist eine
      spezielle, vom Trigger getrennte Prozedurdefinition erforderlich.
    &lt;/p&gt;
  &lt;/li&gt;
  &lt;li class=&quot;sdoc-list-li-point&quot; style=&quot;list-style-type:disc&quot;&gt;
    &lt;p class=&quot;sdoc-para-p&quot;&gt;
      Der Bezeichner für die neue Tabellenzeile ist bei Oracle &lt;tt class=&quot;sdoc-seg-c&quot;&gt;:new&lt;/tt&gt;,
      bei PostgreSQL &lt;tt class=&quot;sdoc-seg-c&quot;&gt;NEW&lt;/tt&gt;. Bei PostgreSQL muss diese Zeile von
      der Trigger-Prozedur zurückgeliefert werden. Bei Oracle wird nichts
      zurückgeliefert.
    &lt;/p&gt;
  &lt;/li&gt;
  &lt;li class=&quot;sdoc-list-li-point&quot; style=&quot;list-style-type:disc&quot;&gt;
    &lt;p class=&quot;sdoc-para-p&quot;&gt;
      PostgreSQL generiert bei &lt;tt class=&quot;sdoc-seg-c&quot;&gt;INTO STRICT&lt;/tt&gt; automatisch eine Exception,
      wenn durch das &lt;tt class=&quot;sdoc-seg-c&quot;&gt;SELECT&lt;/tt&gt; keine oder mehr als eine Zeile getroffen wird.
      Dies ist ein kostenloser Paranoia-Test für die Daten in
      &lt;tt class=&quot;sdoc-seg-c&quot;&gt;&amp;lt;lookup_table&amp;gt;&lt;/tt&gt;.
    &lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt; 
    </content:encoded>

    <pubDate>Fri, 23 Mar 2012 14:35:04 +0100</pubDate>
    <guid isPermaLink="false">http://fseitz.de/blog/index.php?/archives/85-guid.html</guid>
    
</item>

</channel>
</rss>