<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>
<channel>
	<title>Ramblings from the bit bucket &#187; feature enhancement</title>
	<atom:link href="http://blogs.planetingres.org/notnull/tag/feature-enhancement/feed/" rel="self" type="application/rss+xml" />
	<link>http://blogs.planetingres.org/notnull</link>
	<description>Just another blogs.planetingres.org weblog</description>
	<lastBuildDate>Tue, 01 Feb 2011 09:13:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Enhanced Row producing procedures</title>
		<link>http://blogs.planetingres.org/notnull/2008/11/14/enhanced-row-producing-procedures/</link>
		<comments>http://blogs.planetingres.org/notnull/2008/11/14/enhanced-row-producing-procedures/#comments</comments>
		<pubDate>Fri, 14 Nov 2008 21:47:47 +0000</pubDate>
		<dc:creator>notnull</dc:creator>
				<category><![CDATA[database]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Example]]></category>
		<category><![CDATA[ingres]]></category>
		<category><![CDATA[feature enhancement]]></category>
		<category><![CDATA[row producing procedure]]></category>
		<category><![CDATA[table procedure]]></category>
		<guid isPermaLink="false">http://blogs.planetingres.org/notnull/?p=48</guid>
		<description><![CDATA[I was recently asked about the ability to run a row producing procedure from anything other than ESQLC, which reminded me of a couple of feature requests that I have recently made http://community.ingres.com/wiki/Table_Procedure_Enhancements, named result columns for a row producing procedure and the ability to use a row producing procedure in a view definition.  In [...]]]></description>
			<content:encoded><![CDATA[<p>I was recently asked about the ability to run a row producing procedure from anything other than ESQLC, which reminded me of a couple of feature requests that I have recently made <a href="http://community.ingres.com/wiki/Table_Procedure_Enhancements">http://community.ingres.com/wiki/Table_Procedure_Enhancements</a>, named result columns for a row producing procedure and the ability to use a row producing procedure in a view definition.  In addition to these main features the ability to invoke a procedure with positional parameters was added.</p>
<p>I&#8217;m currently using 9.3.0 (int.w32/135) and decided to try out these features.<br />
The CREATE PROCEDURE syntax for return a row has been extended to include column names, my clumsy attempt at a partial description of the syntax follows:</p>
<p><code>&lt;database procedure&gt; ::= CREATE PROCEDURE &lt;procedure name&gt; &lt;procedure parameter list&gt;<br />
RESULT ROW &lt;result row description&gt;<br />
&lt;procedure name&gt; ::= &lt;identifier&gt;</code></p>
<p><code>&lt;procedure parameter list&gt; ::= &lt;None&gt; |<br />
&lt;left paren&gt; &lt;SQL parameter declaration list&gt; &lt;right paren&gt;</code></p>
<p><code>&lt;result row description&gt; ::= &lt;result row column list&gt; |<br />
&lt;result set identifier&gt; &lt;table procedure column list&gt;</code></p>
<p><code>&lt;result set identifier&gt; ::= &lt;identifier&gt;</code></p>
<p><code>&lt;result row column list&gt; ::= &lt;left paren&gt; &lt;row column list element&gt;<br />
[ { &lt;comma&gt; &lt;row column list element&gt; }... ] &lt;right paren&gt;</code></p>
<p><code>&lt;row column list element&gt; ::= &lt;data type&gt; [ &lt;column constraint&gt; ][ &lt;default&gt; ]</code></p>
<p><code>&lt;table procedure column list&gt; ::= &lt;left paren&gt; &lt;table procedure column list element&gt;<br />
[ { &lt;comma&gt; &lt;table procedure column list element&gt; }... ] &lt;right paren&gt;<br />
</code><br />
<code>&lt;table procedure column list element&gt; ::= &lt;column name&gt; &lt;data type&gt; [ &lt;column constraint&gt; ][ &lt;default&gt; ]</code></p>
<p>The procedure can now be exceuted directly from an EXECUTE PROCEDURE statement (requiring esqlc) or as the table procedure in the FROM clause of a SELECT statement.  The latter releasing row producing procedures from the shackles of embedded SQL.</p>
<p>Time for a few simple contrived examples to demonstrate the syntax and use.</p>
<p>A simple table with some data.<br />
<code>create table t1 (c1 integer not null, c2 char(1) not null);</code></p>
<p><code>insert into t1 (c1, c2) values (1, 'A');<br />
insert into t1 (c1, c2) values (2, 'B');<br />
insert into t1 (c1, c2) values (2, 'B');<br />
insert into t1 (c1, c2) values (3, 'C');<br />
insert into t1 (c1, c2) values (3, 'C');<br />
insert into t1 (c1, c2) values (3, 'C');<br />
insert into t1 (c1, c2) values (4, 'D');<br />
insert into t1 (c1, c2) values (4, 'D');<br />
insert into t1 (c1, c2) values (4, 'D');<br />
insert into t1 (c1, c2) values (4, 'D');</code></p>
<p>A monadic procdure that returns a row from the table t1 restricted by value.</p>
<pre>create procedure  p1 (a1 integer not null)
    result row resrow (r1 integer, r2 char(1))
as
declare
    ival integer not null;
    cval char(1) not null;
begin
    for select c1, c2 into :ival, :cval
        from t1
        where c1 = :a1
        do
            return row ( :ival, :cval );
    endfor;
end
</pre>
<p>A dyadic procedure that returns a row from table t1 restricted by values.</p>
<pre>create procedure  p2 (a1 integer not null, a2 char(1) not null)
    result row resrow (r1 integer, r2 char(1))
as
declare
    ival integer not null;
    cval char(1) not null;
begin
    for select c1, c2 into :ival, :cval
        from t1
        where c1 = :a1 and c2 = :a2
        do
            return row ( :ival, :cval );
    endfor;
end</pre>
<p>The original syntax to execute the procedure must be executed from esqlc.</p>
<pre># include &lt;stdio.h&gt;
void
main()
{
exec sql begin declare section;
    int     aval;
    int     ival;
    char    array[2];
    char    *cval = array;
    exec sql end declare section;
    aval = 2;
    exec sql connect test;
    exec sql execute procedure p1(a1 = :aval) result row (:ival, :cval);
    exec sql begin;
        printf("r1 = %d, r2 = %s\n", ival, cval);
    exec sql end;
    exec sql disconnect;
}</pre>
<p>With the feature to execute the procedure in the FROM clause of a SELECT statement you can execute the procedure using<br />
<code>SELECT r1, r2 FROM p1(a1=2);</code></p>
<p>Parameters can be named, positional or a mixture.  Positional parameters must always appear first in the parameter list in a mixture of named and positional parameters.</p>
<p>An example of positional parameters<br />
<code>SELECT r1, r2 FROM p1(2);<br />
SELECT r1, r2 FROM p2(1, 'A');</code></p>
<p>An example of named parameters<br />
<code>SELECT r1, r2 FROM p1(a1=2);<br />
SELECT r1, r2 from p2(a2='A', a1=1);</code></p>
<p>An example of mixed parameters<br />
<code>SELECT r1, r2 FROM p2(1, a2='A');</code></p>
<p>The SELECT query statement that executes the procedure can be used in a VIEW definition and used as usual.</p>
<p><code>CREATE VIEW v1 AS SELECT r1, r2 FROM p1(2);</code></p>
<p>Some simple example queries.</p>
<pre>
-- Aggregate query
SELECT COUNT(p1.r1) AS count, SUM(p1.r1) AS sum FROM p1(4);
+-------------+----------------------+
|count        |sum                   |
+-------------+----------------------+
|            4|                    16|
+-------------+----------------------+
(1 row)
continue
Executing . . .
-- Query using the view defined from table procedure
SELECT t1.*, v1.* FROM t1, v1 WHERE v1.r2='B';
+-------------+----------+-------------+------+
|c1           |c2        |r1           |r2    |
+-------------+----------+-------------+------+
|            1|A         |            2|B     |
|            1|A         |            2|B     |
|            2|B         |            2|B     |
|            2|B         |            2|B     |
|            3|C         |            2|B     |
|            3|C         |            2|B     |
|            2|B         |            2|B     |
|            2|B         |            2|B     |
|            3|C         |            2|B     |
|            3|C         |            2|B     |
|            4|D         |            2|B     |
|            4|D         |            2|B     |
|            3|C         |            2|B     |
|            3|C         |            2|B     |
|            4|D         |            2|B     |
|            4|D         |            2|B     |
|            4|D         |            2|B     |
|            4|D         |            2|B     |
|            4|D         |            2|B     |
|            4|D         |            2|B     |
+-------------+----------+-------------+------+
(20 rows)
continue
Executing . . .
-- Query using both table and view
SELECT t1.*, v1.* FROM (t1 LEFT JOIN v1 ON t1.c1 = v1.r1 AND v1.r2='B');
+-------------+----------+-------------+------+
|c1           |c2        |r1           |r2    |
+-------------+----------+-------------+------+
|            1|A         |             |      |
|            2|B         |            2|B     |
|            2|B         |            2|B     |
|            3|C         |             |      |
|            2|B         |            2|B     |
|            2|B         |            2|B     |
|            3|C         |             |      |
|            4|D         |             |      |
|            3|C         |             |      |
|            4|D         |             |      |
|            4|D         |             |      |
|            4|D         |             |      |
+-------------+----------+-------------+------+
(12 rows)
continue
Executing . . .
-- Query using both table and table procedure
SELECT t1.*, p1.* FROM t1, p1(t1.c1) p1 WHERE p1.r2='B';
+-------------+----------+-------------+------+
|c1           |c2        |r1           |r2    |
+-------------+----------+-------------+------+
|            2|B         |            2|B     |
|            2|B         |            2|B     |
|            2|B         |            2|B     |
|            2|B         |            2|B     |
+-------------+----------+-------------+------+
(4 rows)</pre>
<h3>Related posts</h3>
<ul class="related_post">
<li><a href="http://blogs.planetingres.org/notnull/2010/02/23/useful-or-useless-follow-on-post/" title="Useful or useless? Follow on post &#8230;">Useful or useless? Follow on post &#8230;</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blogs.planetingres.org/notnull/2008/11/14/enhanced-row-producing-procedures/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

