{"id":7050,"date":"2016-05-22T20:40:12","date_gmt":"2016-05-22T18:40:12","guid":{"rendered":"https:\/\/www.salvis.com\/blog\/?p=7050"},"modified":"2023-11-07T22:51:41","modified_gmt":"2023-11-07T21:51:41","slug":"how-to-integrate-your-plsql-generators-in-sql-developer","status":"publish","type":"post","link":"https:\/\/www.salvis.com\/blog\/2016\/05\/22\/how-to-integrate-your-plsql-generators-in-sql-developer\/","title":{"rendered":"How to Integrate Your PL\/SQL Generators in SQL Developer"},"content":{"rendered":"\n<p>About three weeks ago Steven Feuerstein tweeted in his tip <a href=\"https:\/\/twitter.com\/sfonplsql\/status\/726038864746303489\">#501<\/a>\u00a0a link to a generator for the WHEN clause in DML triggers on Oracle Live SQL. Back then I refactored the generator for\u00a0oddgen &#8211; the Oracle community&#8217;s dictionary-driven code generator &#8211; and published the <a href=\"https:\/\/livesql.oracle.com\/apex\/livesql\/file\/content_C73WCRT0FK21A78LLMZJSDW2J.html\">result<\/a> on Oracle Live SQL as well. Some days ago Steven\u00a0tweeted in tip\u00a0<a href=\"https:\/\/twitter.com\/sfonplsql\/status\/733362124676796416\">#514<\/a>\u00a0about generating a standardised table DDL and I thought about a short moment to refactor this generator as well, but decided against it. There are a lot of generators around which write their\u00a0result to DBMS_OUTPUT or into intermediate\/helper tables and I believe\u00a0that it would be more helpful to show how such\u00a0generators could be integrated into oddgen for SQL Developer. If you are overwhelmed by the length of this blog post (as I was) then I suggest that you scroll down to the bottom and look at the 39 seconds of audio-less video to see a generator in action.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Install oddgen for SQL Developer<\/h2>\n\n\n\n<p>I assume that you are already using&nbsp;SQL Developer 4.x. If not then it is about time that you grab the latest version from <a href=\"http:\/\/www.oracle.com\/technetwork\/developer-tools\/sql-developer\/downloads\/index.html\">here<\/a>&nbsp;and install it. It&#8217;s important to note&nbsp;that oddgen requires version 4 of SQL Developer and won&#8217;t run on older versions 3.x, 2.x and 1.x.<\/p>\n\n\n\n<p>SQL Developer comes with a lot of &#8220;internal&#8221; extensions, but third-party extensions need\u00a0to be installed explicitly. To install oddgen for SQL Developer I recommend following the steps in\u00a0<a href=\"https:\/\/www.oddgen.org\/download\/#installation_via_update_center\">installation via update center<\/a>\u00a0on <a href=\"https:\/\/www.oddgen.org\/download\/#installation_via_update_center\">oddgen.org<\/a>.\u00a0If this is not feasible because your company&#8217;s network restricts internet access then <a href=\"https:\/\/www.salvis.com\/blog\/?ddownload=6990\">download the latest version<\/a>\u00a0and <a href=\"https:\/\/www.oddgen.org\/download\/#installation_from_file\">install it from file<\/a>.<\/p>\n\n\n\n<p>To enable the oddgen window, select &#8220;Generators&#8221; from the &#8220;View&#8221; menu as shown in the following picture:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2016\/05\/menu_view_generators.png\"><img wpfc-lazyload-disable=\"true\" loading=\"lazy\" decoding=\"async\" width=\"252\" height=\"155\" src=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2016\/05\/menu_view_generators.png\" alt=\"menu_view_generators\" class=\"wp-image-7074\"\/><\/a><\/figure>\n\n\n\n<p>You are ready for the next steps, when the Generators window appears in the lower left&nbsp;corner within SQL Developer.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2016\/05\/oddgen_generators_window.png\"><img wpfc-lazyload-disable=\"true\" loading=\"lazy\" decoding=\"async\" width=\"298\" height=\"145\" src=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2016\/05\/oddgen_generators_window.png\" alt=\"oddgen_generators_window\" class=\"wp-image-7078\"\/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">2. Install the Original Generator<\/h2>\n\n\n\n<p>If you are going to integrate your existing generator into SQL Developer this step sounds irrelevant. However, I find it useful to install and try\u00a0generators in a fresh environment to ensure I have not missed some dependencies. I&#8217;ve got Steven Feuerstein&#8217;s permission to use his generator\u00a0for this post.\u00a0It&#8217;s\u00a0a standalone PL\/SQL procedure without dependencies.\u00a0We install the generator &#8220;as is&#8221; in our database. I will use a schema named oddgen, but you may use another user\/schema of course. See the <a href=\"https:\/\/raw.githubusercontent.com\/oddgen\/oddgen\/main\/examples\/user\/create_user_oddgen.sql\">create user DDL<\/a> on Github if you are interested to know how I&#8217;ve set up the oddgen user.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(3 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">Steven Feuerstein&#8217;s gen_table_ddl Generator<\/span><span role=\"button\" tabindex=\"0\" data-code=\"-- 1:1 from https:\/\/livesql.oracle.com\/apex\/livesql\/file\/content_DBEO1MIGH5ZQOILUVV85I1UQC.html\nCREATE OR REPLACE PROCEDURE gen_table_ddl ( \n   entity_in     IN VARCHAR2, \n   entities_in   IN VARCHAR2 DEFAULT NULL, \n   add_fky_in    IN BOOLEAN DEFAULT TRUE, \n   prefix_in     IN VARCHAR2 DEFAULT NULL, \n   in_apex_in    IN BOOLEAN DEFAULT FALSE) \nIS \n   c_table_name    CONSTANT VARCHAR2 (100) \n      := prefix_in || NVL (entities_in, entity_in || 's') ; \n \n   c_pkycol_name   CONSTANT VARCHAR2 (100) := entity_in || '_ID'; \n \n   c_user_code     CONSTANT VARCHAR2 (100) \n      := CASE \n            WHEN in_apex_in THEN 'NVL (v (''APP_USER''), USER)' \n            ELSE 'USER' \n         END ; \n \n   PROCEDURE pl (str_in                   IN VARCHAR2, \n                 indent_in                IN INTEGER DEFAULT 3, \n                 num_newlines_before_in   IN INTEGER DEFAULT 0) \n   IS \n   BEGIN \n      FOR indx IN 1 .. num_newlines_before_in \n      LOOP \n         DBMS_OUTPUT.put_line (''); \n      END LOOP; \n \n      DBMS_OUTPUT.put_line (LPAD (' ', indent_in) || str_in); \n   END; \nBEGIN \n   pl ('CREATE TABLE ' || c_table_name || '(', 0); \n   pl (c_pkycol_name || ' INTEGER NOT NULL,'); \n   pl ('created_by VARCHAR2 (132 BYTE) NOT NULL,'); \n   pl ('changed_by VARCHAR2 (132 BYTE) NOT NULL,'); \n   pl ('created_on DATE NOT NULL,'); \n   pl ('changed_on DATE NOT NULL'); \n   pl (');'); \n \n   pl ('CREATE SEQUENCE ' || c_table_name || '_SEQ;', 0, 1); \n   pl ( \n         'CREATE UNIQUE INDEX ' \n      || c_table_name \n      || ' ON ' \n      || c_table_name \n      || '(' \n      || c_pkycol_name \n      || ');', \n      0, \n      1); \n   pl ( \n         'CREATE OR REPLACE TRIGGER ' \n      || c_table_name \n      || '_bir  \n      BEFORE INSERT ON ' \n      || c_table_name, \n      0, \n      1); \n   pl ('FOR EACH ROW DECLARE', 3); \n   pl ('BEGIN', 3); \n   pl ('IF :new.' || c_pkycol_name || ' IS NULL', 6); \n   pl ( \n         'THEN :new.' \n      || c_pkycol_name \n      || ' := ' \n      || c_table_name \n      || '_seq.NEXTVAL; END IF;', \n      6); \n \n   pl (':new.created_on := SYSDATE;', 6); \n   pl (':new.created_by := ' || c_user_code || ';', 6); \n   pl (':new.changed_on := SYSDATE;', 6); \n   pl (':new.changed_by := ' || c_user_code || ';', 6); \n   pl ('END ' || c_table_name || '_bir;', 3); \n \n   pl ('CREATE OR REPLACE TRIGGER ' || c_table_name || '_bur', 0, 1); \n   pl ('BEFORE UPDATE ON ' || c_table_name || ' FOR EACH ROW', 3); \n   pl ('DECLARE', 3); \n   pl ('BEGIN', 3); \n   pl (':new.changed_on := SYSDATE;', 6); \n   pl (':new.changed_by := ' || c_user_code || ';', 6); \n   pl ('END ' || c_table_name || '_bur;', 3); \n \n   pl ('ALTER TABLE ' || c_table_name || ' ADD  \n      (CONSTRAINT ' || c_table_name, \n       0, \n       1); \n   pl ( \n         'PRIMARY KEY (' \n      || c_pkycol_name \n      || ')  \n       USING INDEX ' \n      || c_table_name \n      || ' ENABLE VALIDATE);', \n      3); \n \n   IF add_fky_in \n   THEN \n      pl ( \n            'ALTER TABLE ' \n         || c_table_name \n         || ' ADD (CONSTRAINT fk_' \n         || c_table_name, \n         0, \n         1); \n      pl ('FOREIGN KEY (REPLACE_id)  \n     REFERENCES qdb_REPLACE (REPLACE_id)', 3); \n      pl ('ON DELETE CASCADE ENABLE VALIDATE);', 3); \n   END IF; \nEND;\n\/\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6A9955\">-- 1:1 from https:\/\/livesql.oracle.com\/apex\/livesql\/file\/content_DBEO1MIGH5ZQOILUVV85I1UQC.html<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">CREATE OR REPLACE<\/span><span style=\"color: #D4D4D4\"> PROCEDURE gen_table_ddl ( <\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">   entity_in     <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\">, <\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">   entities_in   <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DEFAULT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">NULL<\/span><span style=\"color: #D4D4D4\">, <\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">   add_fky_in    <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">BOOLEAN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DEFAULT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">TRUE<\/span><span style=\"color: #D4D4D4\">, <\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">   prefix_in     <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DEFAULT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">NULL<\/span><span style=\"color: #D4D4D4\">, <\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">   in_apex_in    <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">BOOLEAN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DEFAULT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">FALSE<\/span><span style=\"color: #D4D4D4\">) <\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">IS<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   c_table_name    <\/span><span style=\"color: #569CD6\">CONSTANT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #B5CEA8\">100<\/span><span style=\"color: #D4D4D4\">) <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      := prefix_in || <\/span><span style=\"color: #DCDCAA\">NVL<\/span><span style=\"color: #D4D4D4\"> (entities_in, entity_in || <\/span><span style=\"color: #CE9178\">&#39;s&#39;<\/span><span style=\"color: #D4D4D4\">) ; <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   c_pkycol_name   <\/span><span style=\"color: #569CD6\">CONSTANT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #B5CEA8\">100<\/span><span style=\"color: #D4D4D4\">) := entity_in || <\/span><span style=\"color: #CE9178\">&#39;_ID&#39;<\/span><span style=\"color: #D4D4D4\">; <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   c_user_code     <\/span><span style=\"color: #569CD6\">CONSTANT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #B5CEA8\">100<\/span><span style=\"color: #D4D4D4\">) <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      := <\/span><span style=\"color: #C586C0\">CASE<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #569CD6\">WHEN<\/span><span style=\"color: #D4D4D4\"> in_apex_in <\/span><span style=\"color: #569CD6\">THEN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&#39;NVL (v (&#39;&#39;APP_USER&#39;&#39;), USER)&#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">ELSE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&#39;USER&#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> ; <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">PROCEDURE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">pl<\/span><span style=\"color: #D4D4D4\"> (str_in                   <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\">, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                 indent_in                <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DEFAULT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                 num_newlines_before_in   <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DEFAULT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">) <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">IS<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">BEGIN<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">FOR<\/span><span style=\"color: #D4D4D4\"> indx <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\"> .. num_newlines_before_in <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">LOOP<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #DCDCAA\">DBMS_OUTPUT.<\/span><span style=\"color: #4EC9B0\">put_line<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #CE9178\">&#39;&#39;<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">END LOOP<\/span><span style=\"color: #D4D4D4\">; <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #DCDCAA\">DBMS_OUTPUT.<\/span><span style=\"color: #4EC9B0\">put_line<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #DCDCAA\">LPAD<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #CE9178\">&#39; &#39;<\/span><span style=\"color: #D4D4D4\">, indent_in) || str_in); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\">; <\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">BEGIN<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl (<\/span><span style=\"color: #CE9178\">&#39;CREATE TABLE &#39;<\/span><span style=\"color: #D4D4D4\"> || c_table_name || <\/span><span style=\"color: #CE9178\">&#39;(&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl (c_pkycol_name || <\/span><span style=\"color: #CE9178\">&#39; INTEGER NOT NULL,&#39;<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl (<\/span><span style=\"color: #CE9178\">&#39;created_by VARCHAR2 (132 BYTE) NOT NULL,&#39;<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl (<\/span><span style=\"color: #CE9178\">&#39;changed_by VARCHAR2 (132 BYTE) NOT NULL,&#39;<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl (<\/span><span style=\"color: #CE9178\">&#39;created_on DATE NOT NULL,&#39;<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl (<\/span><span style=\"color: #CE9178\">&#39;changed_on DATE NOT NULL&#39;<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl (<\/span><span style=\"color: #CE9178\">&#39;);&#39;<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl (<\/span><span style=\"color: #CE9178\">&#39;CREATE SEQUENCE &#39;<\/span><span style=\"color: #D4D4D4\"> || c_table_name || <\/span><span style=\"color: #CE9178\">&#39;_SEQ;&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl ( <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #CE9178\">&#39;CREATE UNIQUE INDEX &#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      || c_table_name <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      || <\/span><span style=\"color: #CE9178\">&#39; ON &#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      || c_table_name <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      || <\/span><span style=\"color: #CE9178\">&#39;(&#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      || c_pkycol_name <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      || <\/span><span style=\"color: #CE9178\">&#39;);&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl ( <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #CE9178\">&#39;CREATE OR REPLACE TRIGGER &#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      || c_table_name <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      || <\/span><span style=\"color: #CE9178\">&#39;_bir  <\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">      BEFORE INSERT ON &#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      || c_table_name, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl (<\/span><span style=\"color: #CE9178\">&#39;FOR EACH ROW DECLARE&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl (<\/span><span style=\"color: #CE9178\">&#39;BEGIN&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl (<\/span><span style=\"color: #CE9178\">&#39;IF :new.&#39;<\/span><span style=\"color: #D4D4D4\"> || c_pkycol_name || <\/span><span style=\"color: #CE9178\">&#39; IS NULL&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">6<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl ( <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #CE9178\">&#39;THEN :new.&#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      || c_pkycol_name <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      || <\/span><span style=\"color: #CE9178\">&#39; := &#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      || c_table_name <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      || <\/span><span style=\"color: #CE9178\">&#39;_seq.NEXTVAL; END IF;&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #B5CEA8\">6<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl (<\/span><span style=\"color: #CE9178\">&#39;:new.created_on := SYSDATE;&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">6<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl (<\/span><span style=\"color: #CE9178\">&#39;:new.created_by := &#39;<\/span><span style=\"color: #D4D4D4\"> || c_user_code || <\/span><span style=\"color: #CE9178\">&#39;;&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">6<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl (<\/span><span style=\"color: #CE9178\">&#39;:new.changed_on := SYSDATE;&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">6<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl (<\/span><span style=\"color: #CE9178\">&#39;:new.changed_by := &#39;<\/span><span style=\"color: #D4D4D4\"> || c_user_code || <\/span><span style=\"color: #CE9178\">&#39;;&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">6<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl (<\/span><span style=\"color: #CE9178\">&#39;END &#39;<\/span><span style=\"color: #D4D4D4\"> || c_table_name || <\/span><span style=\"color: #CE9178\">&#39;_bir;&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl (<\/span><span style=\"color: #CE9178\">&#39;CREATE OR REPLACE TRIGGER &#39;<\/span><span style=\"color: #D4D4D4\"> || c_table_name || <\/span><span style=\"color: #CE9178\">&#39;_bur&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl (<\/span><span style=\"color: #CE9178\">&#39;BEFORE UPDATE ON &#39;<\/span><span style=\"color: #D4D4D4\"> || c_table_name || <\/span><span style=\"color: #CE9178\">&#39; FOR EACH ROW&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl (<\/span><span style=\"color: #CE9178\">&#39;DECLARE&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl (<\/span><span style=\"color: #CE9178\">&#39;BEGIN&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl (<\/span><span style=\"color: #CE9178\">&#39;:new.changed_on := SYSDATE;&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">6<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl (<\/span><span style=\"color: #CE9178\">&#39;:new.changed_by := &#39;<\/span><span style=\"color: #D4D4D4\"> || c_user_code || <\/span><span style=\"color: #CE9178\">&#39;;&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">6<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl (<\/span><span style=\"color: #CE9178\">&#39;END &#39;<\/span><span style=\"color: #D4D4D4\"> || c_table_name || <\/span><span style=\"color: #CE9178\">&#39;_bur;&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl (<\/span><span style=\"color: #CE9178\">&#39;ALTER TABLE &#39;<\/span><span style=\"color: #D4D4D4\"> || c_table_name || <\/span><span style=\"color: #CE9178\">&#39; ADD  <\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">      (CONSTRAINT &#39;<\/span><span style=\"color: #D4D4D4\"> || c_table_name, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">       <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">       <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   pl ( <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #CE9178\">&#39;PRIMARY KEY (&#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      || c_pkycol_name <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      || <\/span><span style=\"color: #CE9178\">&#39;)  <\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">       USING INDEX &#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      || c_table_name <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      || <\/span><span style=\"color: #CE9178\">&#39; ENABLE VALIDATE);&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #C586C0\">IF<\/span><span style=\"color: #D4D4D4\"> add_fky_in <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">THEN<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      pl ( <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #CE9178\">&#39;ALTER TABLE &#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         || c_table_name <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         || <\/span><span style=\"color: #CE9178\">&#39; ADD (CONSTRAINT fk_&#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         || c_table_name, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      pl (<\/span><span style=\"color: #CE9178\">&#39;FOREIGN KEY (REPLACE_id)  <\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">     REFERENCES qdb_REPLACE (REPLACE_id)&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      pl (<\/span><span style=\"color: #CE9178\">&#39;ON DELETE CASCADE ENABLE VALIDATE);&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #C586C0\">END IF<\/span><span style=\"color: #D4D4D4\">; <\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">3. Understand the Input and Output of the Original Generator<\/h2>\n\n\n\n<p>Before we start writing a wrapper for the original generator we need to understand its API. The purpose of the generator is described on Oracle Live SQL by Steven Feuerstein as follows:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>I follow a few standards for table definitions, including: table name is plural; four standard audit columns (created by\/when, updated by\/when) with associated triggers; primary key name is [entity]_id, and more. This procedure (refactored from PL\/SQL Challenge, the quiz website plsqlchallenge.oracle.com) gives me a consisting start point, from which I then add entity-specific columns, additional foreign keys, etc. Hopefully you will find it useful, too!<\/p>\n<\/blockquote>\n\n\n\n<p>The procedure gen_table_ddl expects the following 5 input parameters&nbsp;(see highlighted lines 3 to 7 above):<\/p>\n\n\n\n<table id=\"tablepress-7\" class=\"tablepress tablepress-id-7\">\n<thead>\n<tr class=\"row-1\">\n\t<th class=\"column-1\">Parameter Name<\/th><th class=\"column-2\">Datatype<\/th><th class=\"column-3\">Optional?<\/th><th class=\"column-4\">Default<\/th><th class=\"column-5\">Comments<\/th>\n<\/tr>\n<\/thead>\n<tbody class=\"row-striping row-hover\">\n<tr class=\"row-2\">\n\t<td class=\"column-1\">entity_in<\/td><td class=\"column-2\">varchar2<\/td><td class=\"column-3\">No<\/td><td class=\"column-4\"><\/td><td class=\"column-5\">used to name the primary key column<\/td>\n<\/tr>\n<tr class=\"row-3\">\n\t<td class=\"column-1\">entities_in<\/td><td class=\"column-2\">varchar2<\/td><td class=\"column-3\">Yes<\/td><td class=\"column-4\">entity_in || &#8216;s&#8217;<\/td><td class=\"column-5\">used to name table, sequence, index, triggers and constraints<\/td>\n<\/tr>\n<tr class=\"row-4\">\n\t<td class=\"column-1\">add_fky_in<\/td><td class=\"column-2\">boolean<\/td><td class=\"column-3\">Yes<\/td><td class=\"column-4\">true<\/td><td class=\"column-5\">true: generates a template for a foreign key constraint <br \/>\nfalse: does not generate a foreign key constraint template<\/td>\n<\/tr>\n<tr class=\"row-5\">\n\t<td class=\"column-1\">prefix_in<\/td><td class=\"column-2\">varchar2<\/td><td class=\"column-3\">Yes<\/td><td class=\"column-4\">null<\/td><td class=\"column-5\">prefix for all object names (named by entities_in)<\/td>\n<\/tr>\n<tr class=\"row-6\">\n\t<td class=\"column-1\">in_apex_in<\/td><td class=\"column-2\">boolean<\/td><td class=\"column-3\">Yes<\/td><td class=\"column-4\">false<\/td><td class=\"column-5\">true: uses apex built-in variable APP_USER to populate created_by and changed_by. Uses pseudo column USERS only if APP_USER is empty<br \/>\nfalse: always use pseudo column USER  to populate created_by and changed_by <\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n\n\n\n<p>By now we should have a decent understanding of the procedure input. But how is the output generated? It&#8217;s a procedure after all and there are no output parameters defined. Line 30 reveals the output mechanism. Every line is produced by the nested procedure pl which writes the result to&nbsp;the server output using the DBMS_OUTPUT package.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Understand the Basics of the oddgen PL\/SQL Interface<\/h2>\n\n\n\n<p>When selecting a database connection, the oddgen extension searches\u00a0the data dictionary for PL\/SQL packages implementing\u00a0the oddgen PL\/SQL interface. Basically, it looks\u00a0for a package functions with the following signature:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">FUNCTION generate(in_object_type IN VARCHAR2,\n                  in_object_name IN VARCHAR2,\n                  in_params      IN t_param) RETURN CLOB;<\/pre>\n\n\n\n<p>The interface is designed for generators based on existing database object types such as tables. Therefore it expects the object_type and the object_name as parameters one and two. For our generator, the third parameter is the most interesting one. It allows us to pass additional\u00a0parameters to the generator. The data type t_param is an associative array and\u00a0based on\u00a0the following definition:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">SUBTYPE string_type IS VARCHAR2(1000 CHAR);\nSUBTYPE param_type IS VARCHAR2(60 CHAR);\nTYPE t_param IS TABLE OF string_type INDEX BY param_type;\n<\/pre>\n\n\n\n<p>Through in_params&nbsp;we may pass an unlimited number of key-value pairs to an oddgen generator.<\/p>\n\n\n\n<p>But the oddgen interface is also responsible for defining the representation in the GUI. Let&#8217;s look at an example of another generator named &#8220;Dropall&#8221;:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2016\/05\/oddgen_dropall_generator.png\"><img wpfc-lazyload-disable=\"true\" loading=\"lazy\" decoding=\"async\" width=\"845\" height=\"368\" src=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2016\/05\/oddgen_dropall_generator.png\" alt=\"oddgen_dropall_generator\" class=\"wp-image-7095\" srcset=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2016\/05\/oddgen_dropall_generator.png 845w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2016\/05\/oddgen_dropall_generator-300x131.png 300w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2016\/05\/oddgen_dropall_generator-768x334.png 768w\" sizes=\"auto, (max-width:767px) 480px, (max-width:845px) 100vw, 845px\" \/><\/a><\/figure>\n\n\n\n<p>The &#8220;Dropall&#8221; node is selected and in the status bar, its\u00a0description is displayed. Under this node you find the object types &#8220;Indexes&#8221; and &#8220;Tables&#8221; but also an artificial object type\u00a0named &#8220;All&#8221;. Under the object type nodes, you find the list of all associated object names. This structure supports the following features:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Generate code through a simple double-click on an object name node<\/li>\n\n\n\n<li>Select multiple object name nodes of the same object type to generate code via context-menu<\/li>\n\n\n\n<li>Show a dialog via the context menu for selected object name nodes to change generator parameters<\/li>\n<\/ol>\n\n\n\n<p>When a generator is called, the selected object name and its associated object type are passed to the generator. Always, without exception. However, for artificial object types and object names, it might be okay to\u00a0ignore these\u00a0parameters in the generator implementation.<\/p>\n\n\n\n<p>See the <a href=\"https:\/\/www.oddgen.org\/plsql-interface\/\">oddgen PL\/SQL interface<\/a> documentation on <a href=\"https:\/\/www.oddgen.org\/plsql-interface\/\">oddgen.org<\/a> if you are interested in the details.<\/p>\n\n\n\n<p>For the next steps, it&#8217;s just important to know that we have to define the default behaviour of a generator and that a\u00a0generator provides some information for the GUI only.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5. Write the Wrapper<\/h2>\n\n\n\n<p>The following screenshot shows our&nbsp;generator in SQL Developer after selecting &#8220;Generate&#8230;&#8221; from the context menu on the node &#8220;Snippet&#8221;:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2016\/05\/oddgen_table_ddl_generator.png\"><img wpfc-lazyload-disable=\"true\" loading=\"lazy\" decoding=\"async\" width=\"970\" height=\"610\" src=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2016\/05\/oddgen_table_ddl_generator.png\" alt=\"oddgen_table_ddl_generator\" class=\"wp-image-7100\" srcset=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2016\/05\/oddgen_table_ddl_generator.png 970w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2016\/05\/oddgen_table_ddl_generator-300x189.png 300w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2016\/05\/oddgen_table_ddl_generator-768x483.png 768w\" sizes=\"auto, (max-width:767px) 480px, (max-width:970px) 100vw, 970px\" \/><\/a><\/figure>\n\n\n\n<p>The package specification for this generator looks as follows:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">Package Specification<\/span><span role=\"button\" tabindex=\"0\" data-code=\"CREATE OR REPLACE PACKAGE gen_table_ddl_oddgen_wrapper IS\n   SUBTYPE string_type IS VARCHAR2(1000 CHAR);\n   SUBTYPE param_type IS VARCHAR2(60 CHAR);\n   TYPE t_string IS TABLE OF string_type;\n   TYPE t_param IS TABLE OF string_type INDEX BY param_type;\n   TYPE t_lov IS TABLE OF t_string INDEX BY param_type;\n\n   FUNCTION get_name RETURN VARCHAR2;\n\n   FUNCTION get_description RETURN VARCHAR2;\n\n   FUNCTION get_object_types RETURN t_string;\n\n   FUNCTION get_object_names(in_object_type IN VARCHAR2) RETURN t_string;\n\n   FUNCTION get_params RETURN t_param;\n\n   FUNCTION get_ordered_params RETURN t_string;\n\n   FUNCTION get_lov RETURN t_lov;\n\n   FUNCTION generate(in_object_type IN VARCHAR2,\n                     in_object_name IN VARCHAR2,\n                     in_params      IN t_param) RETURN CLOB;\nEND gen_table_ddl_oddgen_wrapper;\n\/\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">CREATE OR REPLACE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">PACKAGE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">gen_table_ddl_oddgen_wrapper<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">SUBTYPE<\/span><span style=\"color: #D4D4D4\"> string_type <\/span><span style=\"color: #569CD6\">IS<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">1000<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">CHAR<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">SUBTYPE<\/span><span style=\"color: #D4D4D4\"> param_type <\/span><span style=\"color: #569CD6\">IS<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">60<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">CHAR<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">TYPE<\/span><span style=\"color: #D4D4D4\"> t_string <\/span><span style=\"color: #569CD6\">IS<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">TABLE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">OF<\/span><span style=\"color: #D4D4D4\"> string_type;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">TYPE<\/span><span style=\"color: #D4D4D4\"> t_param <\/span><span style=\"color: #569CD6\">IS<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">TABLE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">OF<\/span><span style=\"color: #D4D4D4\"> string_type <\/span><span style=\"color: #569CD6\">INDEX BY<\/span><span style=\"color: #D4D4D4\"> param_type;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">TYPE<\/span><span style=\"color: #D4D4D4\"> t_lov <\/span><span style=\"color: #569CD6\">IS<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">TABLE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">OF<\/span><span style=\"color: #D4D4D4\"> t_string <\/span><span style=\"color: #569CD6\">INDEX BY<\/span><span style=\"color: #D4D4D4\"> param_type;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_name<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_description<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_object_types<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> t_string;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_object_names<\/span><span style=\"color: #D4D4D4\">(in_object_type <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> t_string;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_params<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> t_param;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_ordered_params<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> t_string;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_lov<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> t_lov;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">generate<\/span><span style=\"color: #D4D4D4\">(in_object_type <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                     in_object_name <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                     in_params      <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> t_param) <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">CLOB<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> gen_table_ddl_oddgen_wrapper;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>I&#8217;m going to explain\u00a0some\u00a0parts of the wrapper implementation based on the package body for this oddgen wrapper:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(3 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">Package Body<\/span><span role=\"button\" tabindex=\"0\" data-code=\"CREATE OR REPLACE PACKAGE BODY gen_table_ddl_oddgen_wrapper IS\n   co_entity   CONSTANT param_type := 'Entity name (singular, for PK column)';\n   co_entities CONSTANT param_type := 'Entity name (plural, for object names)';\n   co_add_fky  CONSTANT param_type := 'Add foreign key?';\n   co_prefix   CONSTANT param_type := 'Object prefix';\n   co_in_apex  CONSTANT param_type := 'Data populated through APEX?';\n\n   FUNCTION get_name RETURN VARCHAR2 IS\n   BEGIN\n      RETURN 'Table DDL snippet';\n   END get_name;\n\n   FUNCTION get_description RETURN VARCHAR2 IS\n   BEGIN\n      RETURN 'Steven Feuerstein''s starting point, from which he adds entity-specific columns, additional foreign keys, etc.';\n   END get_description;\n\n   FUNCTION get_object_types RETURN t_string IS\n   BEGIN\n      RETURN NEW t_string('TABLE');\n   END get_object_types;\n\n   FUNCTION get_object_names(in_object_type IN VARCHAR2) RETURN t_string IS\n   BEGIN\n      RETURN NEW t_string('Snippet');\n   END get_object_names;\n\n   FUNCTION get_params RETURN t_param IS\n      l_params t_param;\n   BEGIN\n      l_params(co_entity) := 'employee';\n      l_params(co_entities) := NULL;\n      l_params(co_add_fky) := 'Yes';\n      l_params(co_prefix) := NULL;\n      l_params(co_in_apex) := 'No';\n      RETURN l_params;\n   END get_params;\n\n   FUNCTION get_ordered_params RETURN t_string IS\n   BEGIN\n      RETURN NEW t_string(co_entity, co_entities, co_add_fky, co_prefix);\n   END get_ordered_params;\n\n   FUNCTION get_lov RETURN t_lov IS\n      l_lov t_lov;\n   BEGIN\n      l_lov(co_add_fky) := NEW t_string('Yes', 'No');\n      l_lov(co_in_apex) := NEW t_string('Yes', 'No');\n      RETURN l_lov;\n   END get_lov;\n\n   FUNCTION generate(in_object_type IN VARCHAR2,\n                     in_object_name IN VARCHAR2,\n                     in_params      IN t_param) RETURN CLOB IS\n      l_lines    sys.dbms_output.chararr;\n      l_numlines INTEGER := 10; -- buffer size\n      l_result   CLOB;\n   \n      PROCEDURE enable_output IS\n      BEGIN\n         sys.dbms_output.enable(buffer_size =&gt; NULL); -- unlimited size\n      END enable_output;\n   \n      PROCEDURE disable_output IS\n      BEGIN\n         sys.dbms_output.disable;\n      END disable_output;\n   \n      PROCEDURE call_generator IS\n      BEGIN\n         gen_table_ddl(entity_in   =&gt; in_params(co_entity),\n                       entities_in =&gt; in_params(co_entities),\n                       add_fky_in  =&gt; CASE\n                                         WHEN in_params(co_add_fky) = 'Yes' THEN\n                                          TRUE\n                                         ELSE\n                                          FALSE\n                                      END,\n                       prefix_in   =&gt; in_params(co_prefix),\n                       in_apex_in  =&gt; CASE\n                                         WHEN in_params(co_in_apex) = 'Yes' THEN\n                                          TRUE\n                                         ELSE\n                                          FALSE\n                                      END);\n      END call_generator;\n   \n      PROCEDURE copy_dbms_output_to_result IS\n      BEGIN\n         sys.dbms_lob.createtemporary(l_result, TRUE);\n         <<read_dbms_output_into_buffer&gt;&gt;\n         WHILE l_numlines &gt; 0\n         LOOP\n            sys.dbms_output.get_lines(l_lines, l_numlines);\n            <<copy_buffer_to_clob&gt;&gt;\n            FOR i IN 1 .. l_numlines\n            LOOP\n               sys.dbms_lob.append(l_result, l_lines(i) || chr(10));\n            END LOOP copy_buffer_to_clob;\n         END LOOP read_dbms_output_into_buffer;\n      END copy_dbms_output_to_result;\n   BEGIN\n      enable_output;\n      call_generator;\n      copy_dbms_output_to_result;\n      disable_output;\n      RETURN l_result;\n   END generate;\nEND gen_table_ddl_oddgen_wrapper;\n\/\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">CREATE OR REPLACE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">PACKAGE BODY<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">gen_table_ddl_oddgen_wrapper<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   co_entity   <\/span><span style=\"color: #569CD6\">CONSTANT<\/span><span style=\"color: #D4D4D4\"> param_type := <\/span><span style=\"color: #CE9178\">&#39;Entity name (singular, for PK column)&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   co_entities <\/span><span style=\"color: #569CD6\">CONSTANT<\/span><span style=\"color: #D4D4D4\"> param_type := <\/span><span style=\"color: #CE9178\">&#39;Entity name (plural, for object names)&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   co_add_fky  <\/span><span style=\"color: #569CD6\">CONSTANT<\/span><span style=\"color: #D4D4D4\"> param_type := <\/span><span style=\"color: #CE9178\">&#39;Add foreign key?&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   co_prefix   <\/span><span style=\"color: #569CD6\">CONSTANT<\/span><span style=\"color: #D4D4D4\"> param_type := <\/span><span style=\"color: #CE9178\">&#39;Object prefix&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   co_in_apex  <\/span><span style=\"color: #569CD6\">CONSTANT<\/span><span style=\"color: #D4D4D4\"> param_type := <\/span><span style=\"color: #CE9178\">&#39;Data populated through APEX?&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_name<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&#39;Table DDL snippet&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> get_name;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_description<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&#39;Steven Feuerstein&#39;&#39;s starting point, from which he adds entity-specific columns, additional foreign keys, etc.&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> get_description;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_object_types<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> t_string <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> NEW t_string(<\/span><span style=\"color: #CE9178\">&#39;TABLE&#39;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> get_object_types;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_object_names<\/span><span style=\"color: #D4D4D4\">(in_object_type <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> t_string <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> NEW t_string(<\/span><span style=\"color: #CE9178\">&#39;Snippet&#39;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> get_object_names;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_params<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> t_param <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_params<\/span><span style=\"color: #D4D4D4\"> t_param;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_params<\/span><span style=\"color: #D4D4D4\">(co_entity) := <\/span><span style=\"color: #CE9178\">&#39;employee&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_params<\/span><span style=\"color: #D4D4D4\">(co_entities) := <\/span><span style=\"color: #569CD6\">NULL<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_params<\/span><span style=\"color: #D4D4D4\">(co_add_fky) := <\/span><span style=\"color: #CE9178\">&#39;Yes&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_params<\/span><span style=\"color: #D4D4D4\">(co_prefix) := <\/span><span style=\"color: #569CD6\">NULL<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_params<\/span><span style=\"color: #D4D4D4\">(co_in_apex) := <\/span><span style=\"color: #CE9178\">&#39;No&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">l_params<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> get_params;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_ordered_params<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> t_string <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> NEW t_string(co_entity, co_entities, co_add_fky, co_prefix);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> get_ordered_params;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_lov<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> t_lov <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_lov<\/span><span style=\"color: #D4D4D4\"> t_lov;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_lov<\/span><span style=\"color: #D4D4D4\">(co_add_fky) := NEW t_string(<\/span><span style=\"color: #CE9178\">&#39;Yes&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&#39;No&#39;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_lov<\/span><span style=\"color: #D4D4D4\">(co_in_apex) := NEW t_string(<\/span><span style=\"color: #CE9178\">&#39;Yes&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&#39;No&#39;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">l_lov<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> get_lov;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">generate<\/span><span style=\"color: #D4D4D4\">(in_object_type <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                     in_object_name <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                     in_params      <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> t_param) <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">CLOB<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_lines<\/span><span style=\"color: #D4D4D4\">    sys.<\/span><span style=\"color: #DCDCAA\">dbms_output.<\/span><span style=\"color: #4EC9B0\">chararr<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_numlines<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> := <\/span><span style=\"color: #B5CEA8\">10<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #6A9955\">-- buffer size<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_result<\/span><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">CLOB<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">PROCEDURE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">enable_output<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         sys.<\/span><span style=\"color: #DCDCAA\">dbms_output.<\/span><span style=\"color: #4EC9B0\">enable<\/span><span style=\"color: #D4D4D4\">(buffer_size =&gt; <\/span><span style=\"color: #569CD6\">NULL<\/span><span style=\"color: #D4D4D4\">); <\/span><span style=\"color: #6A9955\">-- unlimited size<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> enable_output;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">PROCEDURE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">disable_output<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         sys.<\/span><span style=\"color: #DCDCAA\">dbms_output.<\/span><span style=\"color: #4EC9B0\">disable<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> disable_output;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">PROCEDURE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">call_generator<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         gen_table_ddl(entity_in   =&gt; in_params(co_entity),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                       entities_in =&gt; in_params(co_entities),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                       add_fky_in  =&gt; <\/span><span style=\"color: #C586C0\">CASE<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                                         <\/span><span style=\"color: #569CD6\">WHEN<\/span><span style=\"color: #D4D4D4\"> in_params(co_add_fky) = <\/span><span style=\"color: #CE9178\">&#39;Yes&#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">THEN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                                          <\/span><span style=\"color: #569CD6\">TRUE<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                                         <\/span><span style=\"color: #C586C0\">ELSE<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                                          <\/span><span style=\"color: #569CD6\">FALSE<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                                      <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                       prefix_in   =&gt; in_params(co_prefix),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                       in_apex_in  =&gt; <\/span><span style=\"color: #C586C0\">CASE<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                                         <\/span><span style=\"color: #569CD6\">WHEN<\/span><span style=\"color: #D4D4D4\"> in_params(co_in_apex) = <\/span><span style=\"color: #CE9178\">&#39;Yes&#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">THEN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                                          <\/span><span style=\"color: #569CD6\">TRUE<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                                         <\/span><span style=\"color: #C586C0\">ELSE<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                                          <\/span><span style=\"color: #569CD6\">FALSE<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                                      <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> call_generator;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">PROCEDURE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">copy_dbms_output_to_result<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         sys.<\/span><span style=\"color: #DCDCAA\">dbms_lob.<\/span><span style=\"color: #4EC9B0\">createtemporary<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">l_result<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">TRUE<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         &lt;&lt;read_dbms_output_into_buffer&gt;&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #C586C0\">WHILE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">l_numlines<\/span><span style=\"color: #D4D4D4\"> &gt; <\/span><span style=\"color: #B5CEA8\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #C586C0\">LOOP<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            sys.<\/span><span style=\"color: #DCDCAA\">dbms_output.<\/span><span style=\"color: #4EC9B0\">get_lines<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">l_lines<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">l_numlines<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            &lt;&lt;copy_buffer_to_clob&gt;&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">FOR<\/span><span style=\"color: #D4D4D4\"> i <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\"> .. <\/span><span style=\"color: #9CDCFE\">l_numlines<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">LOOP<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               sys.<\/span><span style=\"color: #DCDCAA\">dbms_lob.<\/span><span style=\"color: #4EC9B0\">append<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">l_result<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">l_lines<\/span><span style=\"color: #D4D4D4\">(i) || <\/span><span style=\"color: #DCDCAA\">chr<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">10<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">END LOOP<\/span><span style=\"color: #D4D4D4\"> copy_buffer_to_clob;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #C586C0\">END LOOP<\/span><span style=\"color: #D4D4D4\"> read_dbms_output_into_buffer;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> copy_dbms_output_to_result;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">      enable_output;<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">      call_generator;<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">      copy_dbms_output_to_result;<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">      disable_output;<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">l_result<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> generate;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> gen_table_ddl_oddgen_wrapper;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>On lines 1 to 6 constants for every parameter are defined. The values are used as labels in the GUI.<\/p>\n\n\n\n<p>The function get_name (line 10) defines the name used in the GUI for this generator.<\/p>\n\n\n\n<p>The function get_description (line 15) returns a description of the generator. The description is shown in the status bar, as a tooltip and in the generator dialog.<\/p>\n\n\n\n<p>The function get_object_types (line 20) defines the valid object types.\u00a0We&#8217;ve chosen the object type &#8220;TABLE&#8221; because it represents the target code quite well. Using known object types leads also to a nice icon representation.<\/p>\n\n\n\n<p>The function get_object_names (line 25) defines the valid object names for an object type. &nbsp;The parameter in_object_type is not used&nbsp;since our list is static and contains just one value &#8220;Snippet&#8221;.<\/p>\n\n\n\n<p>The function get_params (lines 31-35) defines the list of input parameters for the generator (besides object type and object name). Here we define our five parameters with their default values. The default values are important to generate meaningful code when double-clicking on the object name\u00a0node &#8220;Snippet&#8221;. So, by default, a table named &#8220;employees&#8221; with a foreign key template and triggers for non-APEX usage is generated.<\/p>\n\n\n\n<p>The function get_ordered_params (line 41) defines the order of the parameters in the generator dialog. Such a definition is necessary since the original order is lost. That&#8217;s the expected behaviour for an\u00a0associative array indexed by a string. The default order by name is not very intuitive in this case.<\/p>\n\n\n\n<p>The function get_lovs \u00a0(lines 47-48) defines the list of values per input parameter. We use &#8220;Yes&#8221; and &#8220;No&#8221; for the boolean parameters\u00a0co_add_fky and\u00a0co_in_apex since oddgen supports string parameters only. However, in the GUI typical boolean value pairs such as &#8220;Yes-No&#8221;, &#8220;1-0&#8221;, &#8220;true-false&#8221; are recognised based on the list-of-values definition and are represented as checkboxes. Hence, for\u00a0the user, it does not matter that technically no boolean parameters are used.<\/p>\n\n\n\n<p>The function generates (lines 103-107) defines the steps to produce the generated code. Each step is represented by a nested\u00a0procedure call:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>enable output<\/strong> &#8211; enables the dbms_output with unlimited buffer size<\/li>\n\n\n\n<li><strong>call_generator<\/strong> &#8211; calls the original generator code using the parameters passed by oddgen<\/li>\n\n\n\n<li><strong>copy_dbms_output_to_result<\/strong> &#8211; copies the output of the original generator into the result CLOB<\/li>\n\n\n\n<li><strong>disable_output<\/strong> &#8211; disables dbms_output<\/li>\n<\/ul>\n\n\n\n<p>Finally, the generated code is returned as CLOB.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">6. Grant Access<\/h2>\n\n\n\n<p>To ensure that the generator is available for every user connecting to the\u00a0instance, we have to grant execute rights on\u00a0the PL\/SQL wrapper package. Granting the package to the public is probably the easiest way.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">Grant<\/span><span role=\"button\" tabindex=\"0\" data-code=\"GRANT EXECUTE ON gen_table_ddl_oddgen_wrapper TO PUBLIC;\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">GRANT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">EXECUTE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">ON<\/span><span style=\"color: #D4D4D4\"> gen_table_ddl_oddgen_wrapper <\/span><span style=\"color: #569CD6\">TO<\/span><span style=\"color: #D4D4D4\"> PUBLIC;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">7. Run in SQL Developer<\/h2>\n\n\n\n<p>Now we may run the generator in SQL Developer. The following video is 39 seconds long, contains no audio signal and shows how to generate the DDLs with default parameters and how to run the generator with amended parameters to generate the DDLs for a table\u00a0to be used in an APEX application.<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video controls src=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2016\/05\/gen_table_ddl_oddgen_wrapper.mp4\"><\/video><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">8. Conclusion<\/h2>\n\n\n\n<p>Every PL\/SQL-based code generator producing a document (CLOB, XMLTYPE, JSON), messages via DBMS_OUTPUT or records in tables can be integrated into SQL Developer using the oddgen extension. The effort depends on the number of parameters and their valid values. For simple generators, this won&#8217;t take more than a few minutes, especially if you are an experienced oddgen user.<\/p>\n\n\n\n<p>I hope you found this post useful. Your comments and feedback are very much appreciated.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>About three weeks ago Steven Feuerstein tweeted in his tip #501\u00a0a link to a generator for the WHEN clause in DML triggers on Oracle Live SQL. Back then I refactored the generator for\u00a0oddgen &#8211; the Oracle community&#8217;s dictionary-driven code generator &#8211; and published the result on Oracle Live SQL as well. Some<span class=\"excerpt-hellip\"> [\u2026]<\/span><\/p>\n","protected":false},"author":1,"featured_media":7078,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[94,13,85,87],"class_list":["post-7050","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oracle","tag-oddgen","tag-plsql","tag-sql","tag-sql-developer"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>How to Integrate Your PL\/SQL Generators in SQL Developer - Philipp Salvisberg&#039;s Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.salvis.com\/blog\/2016\/05\/22\/how-to-integrate-your-plsql-generators-in-sql-developer\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Integrate Your PL\/SQL Generators in SQL Developer - Philipp Salvisberg&#039;s Blog\" \/>\n<meta property=\"og:description\" content=\"About three weeks ago Steven Feuerstein tweeted in his tip #501\u00a0a link to a generator for the WHEN clause in DML triggers on Oracle Live SQL. Back then I refactored the generator for\u00a0oddgen &#8211; the Oracle community&#8217;s dictionary-driven code generator &#8211; and published the result on Oracle Live SQL as well. Some [\u2026]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.salvis.com\/blog\/2016\/05\/22\/how-to-integrate-your-plsql-generators-in-sql-developer\/\" \/>\n<meta property=\"og:site_name\" content=\"Philipp Salvisberg&#039;s Blog\" \/>\n<meta property=\"article:published_time\" content=\"2016-05-22T18:40:12+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-11-07T21:51:41+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2016\/05\/oddgen_generators_window.png\" \/>\n\t<meta property=\"og:image:width\" content=\"298\" \/>\n\t<meta property=\"og:image:height\" content=\"145\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Philipp Salvisberg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@phsalvisberg\" \/>\n<meta name=\"twitter:site\" content=\"@phsalvisberg\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Philipp Salvisberg\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2016\\\/05\\\/22\\\/how-to-integrate-your-plsql-generators-in-sql-developer\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2016\\\/05\\\/22\\\/how-to-integrate-your-plsql-generators-in-sql-developer\\\/\"},\"author\":{\"name\":\"Philipp Salvisberg\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\"},\"headline\":\"How to Integrate Your PL\\\/SQL Generators in SQL Developer\",\"datePublished\":\"2016-05-22T18:40:12+00:00\",\"dateModified\":\"2023-11-07T21:51:41+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2016\\\/05\\\/22\\\/how-to-integrate-your-plsql-generators-in-sql-developer\\\/\"},\"wordCount\":1607,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\"},\"image\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2016\\\/05\\\/22\\\/how-to-integrate-your-plsql-generators-in-sql-developer\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2016\\\/05\\\/oddgen_generators_window.png\",\"keywords\":[\"oddgen\",\"PL\\\/SQL\",\"SQL\",\"SQL Developer\"],\"articleSection\":[\"Oracle\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2016\\\/05\\\/22\\\/how-to-integrate-your-plsql-generators-in-sql-developer\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2016\\\/05\\\/22\\\/how-to-integrate-your-plsql-generators-in-sql-developer\\\/\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2016\\\/05\\\/22\\\/how-to-integrate-your-plsql-generators-in-sql-developer\\\/\",\"name\":\"How to Integrate Your PL\\\/SQL Generators in SQL Developer - Philipp Salvisberg&#039;s Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2016\\\/05\\\/22\\\/how-to-integrate-your-plsql-generators-in-sql-developer\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2016\\\/05\\\/22\\\/how-to-integrate-your-plsql-generators-in-sql-developer\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2016\\\/05\\\/oddgen_generators_window.png\",\"datePublished\":\"2016-05-22T18:40:12+00:00\",\"dateModified\":\"2023-11-07T21:51:41+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2016\\\/05\\\/22\\\/how-to-integrate-your-plsql-generators-in-sql-developer\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2016\\\/05\\\/22\\\/how-to-integrate-your-plsql-generators-in-sql-developer\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2016\\\/05\\\/22\\\/how-to-integrate-your-plsql-generators-in-sql-developer\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2016\\\/05\\\/oddgen_generators_window.png\",\"contentUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2016\\\/05\\\/oddgen_generators_window.png\",\"width\":298,\"height\":145},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2016\\\/05\\\/22\\\/how-to-integrate-your-plsql-generators-in-sql-developer\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to Integrate Your PL\\\/SQL Generators in SQL Developer\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/\",\"name\":\"Philipp Salvisberg&#039;s Blog\",\"description\":\"Database-centric development\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\",\"name\":\"Philipp Salvisberg\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\",\"contentUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\",\"width\":400,\"height\":400,\"caption\":\"Philipp Salvisberg\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\"},\"sameAs\":[\"http:\\\/\\\/www.salvis.com\\\/\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"How to Integrate Your PL\/SQL Generators in SQL Developer - Philipp Salvisberg&#039;s Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.salvis.com\/blog\/2016\/05\/22\/how-to-integrate-your-plsql-generators-in-sql-developer\/","og_locale":"en_US","og_type":"article","og_title":"How to Integrate Your PL\/SQL Generators in SQL Developer - Philipp Salvisberg&#039;s Blog","og_description":"About three weeks ago Steven Feuerstein tweeted in his tip #501\u00a0a link to a generator for the WHEN clause in DML triggers on Oracle Live SQL. Back then I refactored the generator for\u00a0oddgen &#8211; the Oracle community&#8217;s dictionary-driven code generator &#8211; and published the result on Oracle Live SQL as well. Some [\u2026]","og_url":"https:\/\/www.salvis.com\/blog\/2016\/05\/22\/how-to-integrate-your-plsql-generators-in-sql-developer\/","og_site_name":"Philipp Salvisberg&#039;s Blog","article_published_time":"2016-05-22T18:40:12+00:00","article_modified_time":"2023-11-07T21:51:41+00:00","og_image":[{"width":298,"height":145,"url":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2016\/05\/oddgen_generators_window.png","type":"image\/png"}],"author":"Philipp Salvisberg","twitter_card":"summary_large_image","twitter_creator":"@phsalvisberg","twitter_site":"@phsalvisberg","twitter_misc":{"Written by":"Philipp Salvisberg","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.salvis.com\/blog\/2016\/05\/22\/how-to-integrate-your-plsql-generators-in-sql-developer\/#article","isPartOf":{"@id":"https:\/\/www.salvis.com\/blog\/2016\/05\/22\/how-to-integrate-your-plsql-generators-in-sql-developer\/"},"author":{"name":"Philipp Salvisberg","@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515"},"headline":"How to Integrate Your PL\/SQL Generators in SQL Developer","datePublished":"2016-05-22T18:40:12+00:00","dateModified":"2023-11-07T21:51:41+00:00","mainEntityOfPage":{"@id":"https:\/\/www.salvis.com\/blog\/2016\/05\/22\/how-to-integrate-your-plsql-generators-in-sql-developer\/"},"wordCount":1607,"commentCount":0,"publisher":{"@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515"},"image":{"@id":"https:\/\/www.salvis.com\/blog\/2016\/05\/22\/how-to-integrate-your-plsql-generators-in-sql-developer\/#primaryimage"},"thumbnailUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2016\/05\/oddgen_generators_window.png","keywords":["oddgen","PL\/SQL","SQL","SQL Developer"],"articleSection":["Oracle"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.salvis.com\/blog\/2016\/05\/22\/how-to-integrate-your-plsql-generators-in-sql-developer\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.salvis.com\/blog\/2016\/05\/22\/how-to-integrate-your-plsql-generators-in-sql-developer\/","url":"https:\/\/www.salvis.com\/blog\/2016\/05\/22\/how-to-integrate-your-plsql-generators-in-sql-developer\/","name":"How to Integrate Your PL\/SQL Generators in SQL Developer - Philipp Salvisberg&#039;s Blog","isPartOf":{"@id":"https:\/\/www.salvis.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.salvis.com\/blog\/2016\/05\/22\/how-to-integrate-your-plsql-generators-in-sql-developer\/#primaryimage"},"image":{"@id":"https:\/\/www.salvis.com\/blog\/2016\/05\/22\/how-to-integrate-your-plsql-generators-in-sql-developer\/#primaryimage"},"thumbnailUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2016\/05\/oddgen_generators_window.png","datePublished":"2016-05-22T18:40:12+00:00","dateModified":"2023-11-07T21:51:41+00:00","breadcrumb":{"@id":"https:\/\/www.salvis.com\/blog\/2016\/05\/22\/how-to-integrate-your-plsql-generators-in-sql-developer\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.salvis.com\/blog\/2016\/05\/22\/how-to-integrate-your-plsql-generators-in-sql-developer\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.salvis.com\/blog\/2016\/05\/22\/how-to-integrate-your-plsql-generators-in-sql-developer\/#primaryimage","url":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2016\/05\/oddgen_generators_window.png","contentUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2016\/05\/oddgen_generators_window.png","width":298,"height":145},{"@type":"BreadcrumbList","@id":"https:\/\/www.salvis.com\/blog\/2016\/05\/22\/how-to-integrate-your-plsql-generators-in-sql-developer\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.salvis.com\/blog\/"},{"@type":"ListItem","position":2,"name":"How to Integrate Your PL\/SQL Generators in SQL Developer"}]},{"@type":"WebSite","@id":"https:\/\/www.salvis.com\/blog\/#website","url":"https:\/\/www.salvis.com\/blog\/","name":"Philipp Salvisberg&#039;s Blog","description":"Database-centric development","publisher":{"@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.salvis.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515","name":"Philipp Salvisberg","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg","url":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg","contentUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg","width":400,"height":400,"caption":"Philipp Salvisberg"},"logo":{"@id":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg"},"sameAs":["http:\/\/www.salvis.com\/"]}]}},"_links":{"self":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts\/7050","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/comments?post=7050"}],"version-history":[{"count":56,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts\/7050\/revisions"}],"predecessor-version":[{"id":12596,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts\/7050\/revisions\/12596"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/media\/7078"}],"wp:attachment":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/media?parent=7050"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/categories?post=7050"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/tags?post=7050"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}