{"id":685,"date":"2015-08-13T10:31:20","date_gmt":"2015-08-13T08:31:20","guid":{"rendered":"http:\/\/www.pitss.org\/blog\/?p=685"},"modified":"2015-08-13T10:31:20","modified_gmt":"2015-08-13T08:31:20","slug":"sql-forward-declaration-erleichtert-refaktorierung-in-der-datenbank","status":"publish","type":"post","link":"https:\/\/pitss.org\/de\/sql-forward-declaration-erleichtert-refaktorierung-in-der-datenbank\/","title":{"rendered":"SQL Forward Declaration erleichtert Refaktorierung in der Datenbank"},"content":{"rendered":"<p>Es gibt viele Gr\u00fcnde, Strukturen in der Datenbank aufzur\u00e4umen und reorganisieren. Sei es in gewachsenen Applikationen, sei es bei der Modernisierung oder dem Zugriff von weiteren Front-Ends auf die gleichen Datenbank Sourcen. Selbst wenn eine komplett neue Architektur aus einer Modellierung \u00fcbernommen werden soll, wird recht schnell klar, dass die Datenbank-Objekte in der richtigen Reihenfolge angelegt werden m\u00fcssen. Das ist zun\u00e4chst offensichtlich und jedem klar. Sequences vor Tabellen, Tabellen vor Views vor PL\/SQL-Funktionen und Prozeduren &#8230;<\/p>\n<p>Schwieriger zu bestimmen\u00a0wird es, wenn gleiche Objekt-Typen untereinander abh\u00e4ngig sind, z.B. wenn Typen auf Typen aufsetzen. Hier die richtige Reihenfolge zu bestimmen ist nicht immer trivial, gerade dann, wenn die Aufgabe darin besteht, in einem skript-gesteuerten Ansatz eine beliebige Vielzahl von TYPE Deklarationen zu erstellen.<\/p>\n<p>Eine gute M\u00f6glichkeit bietet hier die M\u00f6glichkeit, in der Oracle Datenbank &#8222;incomplete Types&#8220; zu erstellen:<br \/>\n<a href=\"http:\/\/docs.oracle.com\/database\/121\/LNPLS\/create_type.htm\" target=\"_blank\">Oracle TYPE Syntax<\/a><\/p>\n<p>Durch die reine Angabe des Typ-Namen bei dem CREATE-Statement kann dieser Typ zun\u00e4chst in weiteren Statements genutzt werden und die Implementierung und genaue Spezifikation kann in einem weiteren Verlauf erfolgen. Mit dieser Forward-Deklaration ist eine Ermittlung der Reihenfolge nicht mehr relevant und es k\u00f6nnen zuerst alle Typen incomplete erstellt werden, bevor die eigentliche Implementierung erfolgt. F\u00fcr einzelne Skripte kann alternativ auch im &#8222;Prefix&#8220; des Skripts sichergestellt werden, dass alle benutzten Typen in einer Forward-Deklaration zun\u00e4chst angelegt werden.<\/p>\n<p>In gr\u00f6\u00dferen Modernisierungsprojekten liegen nach einer Refakturierung die Metadaten h\u00e4ufig in eigenen Tabellen-Strukturen vor. Aus diesen lassen sich dann sehr leicht \u00fcber Velocity\/Texen die passenden Templates f\u00fcr die Generierung der SQL-Skripte erstellen. Bei der Forward-Deklaration der Typen kann dann eine Metadaten-Tabelle und das passende \u00a0Velocity-Template so aussehen:<\/p>\n<table dir=\"ltr\" border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<colgroup>\n<col width=\"120\" \/>\n<col width=\"120\" \/>\n<col width=\"120\" \/>\n<col width=\"287\" \/><\/colgroup>\n<tbody>\n<tr>\n<td>SORT<\/td>\n<td>Object_Name<\/td>\n<td>Object_type<\/td>\n<td>object_value<\/td>\n<\/tr>\n<tr>\n<td>1<\/td>\n<td>beispiel_ot<\/td>\n<td>OT<\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td>2<\/td>\n<td>name_attribut1<\/td>\n<td>R<\/td>\n<td>tabelle1.spalte2<\/td>\n<\/tr>\n<tr>\n<td>3<\/td>\n<td>name_attribut3<\/td>\n<td>N<\/td>\n<td>varchar2(100)<\/td>\n<\/tr>\n<tr>\n<td>4<\/td>\n<td>name_attribut4<\/td>\n<td>N<\/td>\n<td>number(12,2)<\/td>\n<\/tr>\n<tr>\n<td>5<\/td>\n<td>name_attribut5<\/td>\n<td>T<\/td>\n<td>anderer_ot<\/td>\n<\/tr>\n<tr>\n<td>6<\/td>\n<td>name_attribut6<\/td>\n<td>C<\/td>\n<td>base_type<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Dabei kann innerhalb des Object_types unterschieden werden:<\/p>\n<ul>\n<li>R: verweist auf den Spalten-Typ einer existenten Tabelle<\/li>\n<li>N: normaler, simple Oracle Datentyp, z.B. Number, Date, varchar, &#8230;<\/li>\n<li>T: Nutzt einen anderen, selbst definierten Datentypen als SubType<\/li>\n<li>C: collection eines Base_type<\/li>\n<\/ul>\n<p>In der Velocity-Datei wird dann zun\u00e4chst f\u00fcr alle Typen die Forward-Deklaration angelegt, bevor im zweiten Loop die Implementierung erfolgt:<\/p>\n<pre>*#\n#* Forward-Deklaration der benutzen Objekttypen *#\n#foreach($row in $rows)\n   #if($row.OBJECT_TYPE==\"T\" || $row.OBJECT_TYPE==\"C\")\n      CREATE TYPE $row.OBJECT_VALUE;\n   #end\n   #if($row.OBJECT_TYPE==\"C\")\n      CREATE TYPE ${row.OBJECT_VALUE}_COL IS TABLE OF $row.OBJECT_VALUE;\n   #end\n#end\n#. Abschluss der notwendigen Forward-Deklarationen, \n#. um den Typen fehlerfrei erstellen zu k\u00f6nnen\n\nCREATE OR REPLACE \nTYPE $commonsStr.upperCase($strings.concat([\"ty_\", $object_name]))\nFORCE\n\/*\n OBJECT TYPE: $object_name\n\n Beschreibung:\n#foreach($row in $rows)\n   #if($row.OBJECT_TYPE==\"OC\")\n      $commonsStr.replaceOnce($row.OBJECT_DESC,\"--\",\"&gt;\")\n   #end\n#end\n#set($D=\"$\")\n SVN-Info: ${D}HeadURL${D}\n : ${D}Id${D}\n\n Autoren:\n 18.03.2015 PITSS.CON Automatische Generierung\n\n LEGENDE: ... &gt; neu, \u00c4nderung, ! Bugfix, &lt; entfernt\n\n HISTORIE:\n (start table)\n Vers. Wann Wer Was\n 1.00 , 18.03.2015, PITSS.CON, *Neuerstellung\n (end)\n*\/\nIS\n--\nOBJECT\n(\n\n#foreach($row in $rows)\n   #if($row.OBJECT_TYPE ==\"R\" || $row.OBJECT_TYPE ==\"N\" || $row.OBJECT_TYPE ==\"T\" || $row.OBJECT_TYPE ==\"C\" )\n      #set($last_sort=\"0\")\n      #if($last_sort==$row.SORT),#end\n      #set($last_sort=$row.SORT)\n      #if($row.OBJECT_TYPE ==\"C\")\n          ${row.OBJECT_NAME} ${row.OBJECT_VALUE}_COL ${row.OBJECT_DESC} \n      #else\n          ${row.OBJECT_NAME} ${row.OBJECT_VALUE} ${row.OBJECT_DESC} \n      #end#end#end\n...\n\n);\n\/\n\nSHOW ERRORS;\n\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Es gibt viele Gr\u00fcnde, Strukturen in der Datenbank aufzur\u00e4umen und reorganisieren. Sei es in gewachsenen Applikationen, sei es bei der Modernisierung oder dem Zugriff von weiteren Front-Ends auf die gleichen Datenbank Sourcen. Selbst wenn eine komplett neue Architektur aus einer Modellierung \u00fcbernommen werden soll, wird recht schnell klar, dass die Datenbank-Objekte in der richtigen Reihenfolge [&hellip;]<\/p>\n","protected":false},"author":45,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"categories":[113,100,83,84,101,136],"tags":[135],"class_list":["post-685","post","type-post","status-publish","format-standard","hentry","category-entwicklung","category-general","category-oracle","category-pitss","category-pitss-con","category-scripte","tag-forward-declaration"],"_links":{"self":[{"href":"https:\/\/pitss.org\/de\/wp-json\/wp\/v2\/posts\/685","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pitss.org\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pitss.org\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pitss.org\/de\/wp-json\/wp\/v2\/users\/45"}],"replies":[{"embeddable":true,"href":"https:\/\/pitss.org\/de\/wp-json\/wp\/v2\/comments?post=685"}],"version-history":[{"count":0,"href":"https:\/\/pitss.org\/de\/wp-json\/wp\/v2\/posts\/685\/revisions"}],"wp:attachment":[{"href":"https:\/\/pitss.org\/de\/wp-json\/wp\/v2\/media?parent=685"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pitss.org\/de\/wp-json\/wp\/v2\/categories?post=685"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pitss.org\/de\/wp-json\/wp\/v2\/tags?post=685"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}