haul 02/01/31 08:11:33 Modified: . changes.xml src/java/org/apache/cocoon/components/language/markup/xsp EsqlQuery.java src/java/org/apache/cocoon/components/language/markup/xsp/java esql.xsl src/documentation/xdocs/userdocs/xsp esql.xml Log: Stored Procedure support for esql Revision Changes Path 1.86 +4 -3 xml-cocoon2/changes.xml Index: changes.xml =================================================================== RCS file: /home/cvs/xml-cocoon2/changes.xml,v retrieving revision 1.85 retrieving revision 1.86 diff -u -r1.85 -r1.86 --- changes.xml 31 Jan 2002 13:29:48 -0000 1.85 +++ changes.xml 31 Jan 2002 16:11:32 -0000 1.86 @@ -4,7 +4,7 @@ <!-- History of Cocoon changes - $Id: changes.xml,v 1.85 2002/01/31 13:29:48 cziegeler Exp $ + $Id: changes.xml,v 1.86 2002/01/31 16:11:32 haul Exp $ --> <changes title="History of Changes"> @@ -31,8 +31,9 @@ </devs> <release version="@version@" date="@date@"> - <action dev="dummy" type="fix"> - dummy + <action dev="CH" type="add"> + Stored Procedure support for esql plus ability to obtain and use a result + set from any column just like a nested query. </action> </release> <release version="2.0.1" date="January 31, 2002"> 1.3 +71 -9 xml-cocoon2/src/java/org/apache/cocoon/components/language/markup/xsp/EsqlQuery.java Index: EsqlQuery.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/language/markup/xsp/EsqlQuery.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- EsqlQuery.java 28 Jan 2002 09:37:16 -0000 1.2 +++ EsqlQuery.java 31 Jan 2002 16:11:33 -0000 1.3 @@ -10,6 +10,7 @@ import java.sql.Connection; import java.sql.Statement; import java.sql.PreparedStatement; +import java.sql.CallableStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; @@ -30,6 +31,7 @@ private ResultSet resultSet = null; private ResultSetMetaData resultSetMetaData = null; private boolean hasResultSet = false; + private boolean resultSetValid = false; private int position = -1; private int maxRows = -1; private int skipRows = 0; @@ -45,6 +47,14 @@ this.query = query; } + public EsqlQuery( ResultSet aResultSet ) { + this.connection = null; + this.statement = null; + this.query = null; + this.resultSetValid = true; + this.hasResultSet = (this.resultSet != null); + } + public int getSkipRows() { return(skipRows); } @@ -118,10 +128,27 @@ return(preparedStatement); } + + public CallableStatement prepareCall() throws SQLException { + switch(limitMethod) { + case EsqlConnection.LIMIT_METHOD_JDBC: + preparedStatement = connection.prepareCall( getQueryString(), ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); + break; + default: + preparedStatement = connection.prepareCall( getQueryString() ); + }; + statement = preparedStatement; + return((CallableStatement)preparedStatement); + } + public PreparedStatement getPreparedStatement() { return(preparedStatement); } + public CallableStatement getCallableStatement() { + return((CallableStatement) preparedStatement); + } + public ResultSet getResultSet() { return(resultSet); } @@ -171,13 +198,45 @@ } public boolean execute() throws SQLException { - if (preparedStatement != null) { - hasResultSet = preparedStatement.execute(); - } - else { - hasResultSet = statement.execute( getQueryString() ); - } - return(hasResultSet); + return this.execute(false); + } + + /** + * some brain dead DBMSs (Oracle) return their result sets for + * callable statements through the some (i.e. the first) returned + * object. + */ + public boolean execute( int resultSetFromObject ) throws SQLException { + hasResultSet = this.execute(false); + resultSet = (ResultSet) ((CallableStatement) preparedStatement).getObject(1); + resultSetValid = true; + return hasResultSet; + } + + /** + * some other brain dead DBMSs (Informix) don't like their callable + * statements to be 'execute'd but require 'executeQuery' instead. + */ + public boolean execute( boolean needsQuery ) throws SQLException { + if ( needsQuery ) { + if (preparedStatement != null) { + resultSet = preparedStatement.executeQuery(); + } + else { + resultSet = statement.executeQuery( getQueryString() ); + } + hasResultSet = (resultSet != null); + resultSetValid = true; + } else { + if (preparedStatement != null) { + hasResultSet = preparedStatement.execute(); + } + else { + hasResultSet = statement.execute( getQueryString() ); + } + resultSetValid = false; + } + return(hasResultSet); } public boolean hasResultSet() { @@ -209,8 +268,11 @@ } public void getResultRows() throws SQLException { - resultSet = statement.getResultSet(); - resultSetMetaData = resultSet.getMetaData(); + if ( resultSetValid ) { + resultSetMetaData = resultSet.getMetaData(); + } else { + resultSet = statement.getResultSet(); + } if (skipRows > 0) { switch(limitMethod) { 1.5 +137 -23 xml-cocoon2/src/java/org/apache/cocoon/components/language/markup/xsp/java/esql.xsl Index: esql.xsl =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/language/markup/xsp/java/esql.xsl,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- esql.xsl 28 Jan 2002 09:37:16 -0000 1.4 +++ esql.xsl 31 Jan 2002 16:11:33 -0000 1.5 @@ -1,5 +1,5 @@ <?xml version="1.0"?> -<!-- $Id: esql.xsl,v 1.4 2002/01/28 09:37:16 tcurdt Exp $--> +<!-- $Id: esql.xsl,v 1.5 2002/01/31 16:11:33 haul Exp $--> <!-- ============================================================================ @@ -205,6 +205,7 @@ <xsp:include>java.sql.Connection</xsp:include> <xsp:include>java.sql.Statement</xsp:include> <xsp:include>java.sql.PreparedStatement</xsp:include> + <xsp:include>java.sql.CallableStatement</xsp:include> <xsp:include>java.sql.ResultSet</xsp:include> <xsp:include>java.sql.ResultSetMetaData</xsp:include> <xsp:include>java.sql.Struct</xsp:include> @@ -437,7 +438,9 @@ <xsl:template match="esql:connection/esql:property"/> <xsl:template match="esql:connection//esql:execute-query"> - <xsl:variable name="query"><xsl:call-template name="get-nested-string"><xsl:with-param name="content" select="esql:query"/></xsl:call-template></xsl:variable> + + <xsl:variable name="query"><xsl:choose><xsl:when test="esql:query"><xsl:call-template name="get-nested-string"><xsl:with-param name="content" select="esql:query"/></xsl:call-template></xsl:when><xsl:when test="esql:call"><xsl:call-template name="get-nested-string"><xsl:with-param name="content" select="esql:call"/></xsl:call-template></xsl:when></xsl:choose></xsl:variable> + <xsl:variable name="maxrows"><xsl:call-template name="get-nested-string"><xsl:with-param name="content" select="esql:max-rows"/></xsl:call-template></xsl:variable> <xsl:variable name="skiprows"><xsl:call-template name="get-nested-string"><xsl:with-param name="content" select="esql:skip-rows"/></xsl:call-template></xsl:variable> <xsp:logic> @@ -460,6 +463,46 @@ try { <xsl:choose> + <xsl:when test="esql:call"> + try { + _esql_query.prepareCall(); + } catch (SQLException _esql_exception_<xsl:value-of select="generate-id(.)"/>) { + throw new RuntimeException("Error preparing statement: " + _esql_query.getQueryString() + ": "+_esql_exception_<xsl:value-of select="generate-id(.)"/>.getMessage()); + } + <xsl:for-each select="esql:call//esql:parameter"> + try { + <xsl:if test="@direction='out' or @direction='inout'"> + <xsl:text>_esql_query.getCallableStatement().</xsl:text> + registerOutParameter(<xsl:value-of select="position()"/>, Types.<xsl:call-template name="get-Sql-Type"><xsl:with-param name="type"><xsl:value-of select="@type"/></xsl:with-param></xsl:call-template><xsl:if test="@typename">, <xsl:value-of select="@typename"/> </xsl:if>); + </xsl:if> + <xsl:if test="not(@direction) or @direction='inout' or @direction='in'"> + <xsl:text>_esql_query.getCallableStatement().</xsl:text> + <xsl:choose> + <xsl:when test="@type"> + <xsl:variable name="type"><xsl:value-of select="concat(translate(substring(@type,1,1),'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ'),substring(@type,2))"/></xsl:variable> + <xsl:text>set</xsl:text><xsl:value-of select="$type"/>(<xsl:value-of select="position()"/>,<xsl:call-template name="get-nested-content"><xsl:with-param name="content" select="."/></xsl:call-template>);<xsl:text> +</xsl:text> + </xsl:when> + <xsl:otherwise> + <xsl:text>setString(</xsl:text><xsl:value-of select="position()"/>,String.valueOf(<xsl:call-template name="get-nested-string"><xsl:with-param name="content" select="."/></xsl:call-template>));<xsl:text> +</xsl:text> + </xsl:otherwise> + </xsl:choose> + </xsl:if> + } catch (SQLException _esql_exception_<xsl:value-of select="generate-id(.)"/>) { + throw new RuntimeException("Error setting parameter on statement: " + _esql_query.getQueryString() + ": "+_esql_exception_<xsl:value-of select="generate-id(.)"/>); + } + </xsl:for-each> + try { + <xsl:choose> + <xsl:when test="esql:call[@needs-query='true' or @needs-query='yes']">_esql_query.execute(true);</xsl:when> + <xsl:when test="esql:call[@resultset-from-object]">_esql_query.execute(<xsl:copy-of select="esql:call[@resultset-from-object]"/>);</xsl:when> + <xsl:otherwise>_esql_query.execute();</xsl:otherwise> + </xsl:choose> + } catch (SQLException _esql_exception_<xsl:value-of select="generate-id(.)"/>) { + throw new RuntimeException("Error executing prepared statement: " + _esql_query.getQueryString() + ": "+_esql_exception_<xsl:value-of select="generate-id(.)"/>); + } + </xsl:when> <xsl:when test="esql:query//esql:parameter"> try { _esql_query.prepareStatement(); @@ -507,6 +550,12 @@ getLogger().debug("esql query: " + _esql_query.getQueryString()); </xsl:otherwise> </xsl:choose> + <xsl:if test="esql:call"> + // call results + <xsp:content> + <xsl:apply-templates select="esql:call-results"/> + </xsp:content> + </xsl:if> if (_esql_query.hasResultSet()) { do { _esql_query.getResultRows(); @@ -559,6 +608,7 @@ </xsl:template> <xsl:template match="esql:query//esql:parameter">"?"</xsl:template> +<xsl:template match="esql:call//esql:parameter">"?"</xsl:template> <xsl:template match="esql:execute-query//esql:results//esql:row-count"> <xsp:expr>_esql_query.rowCount()</xsp:expr> @@ -570,6 +620,15 @@ </xsp:content> </xsl:template> +<xsl:template match="esql:execute-query//esql:call-results"> + <xsp:logic> + // call results2 + </xsp:logic> + <xsp:content> + <xsl:apply-templates/> + </xsp:content> +</xsl:template> + <xsl:template match="esql:execute-query//esql:error-results"> <xsp:content> <xsl:apply-templates/> @@ -781,7 +840,7 @@ </xsl:template> <xspdoc:desc>returns the value of the given column as a string</xspdoc:desc> -<xsl:template match="esql:row-results//esql:get-string" name="get-string"> +<xsl:template match="esql:row-results//esql:get-string|esql:call-results//esql:get-string" name="get-string"> <xsp:expr> <xsl:call-template name="get-string-encoded"> <xsl:with-param name="column-spec"><xsl:call-template name="get-column"/></xsl:with-param> @@ -791,7 +850,7 @@ </xsl:template> <xspdoc:desc>returns the value of the given column as a date. if a format attribute exists, its value is taken to be a date format string as defined in java.text.SimpleDateFormat, and the result is formatted accordingly.</xspdoc:desc> -<xsl:template match="esql:row-results//esql:get-date"> +<xsl:template match="esql:row-results//esql:get-date|esql:call-results//esql:get-date"> <xsl:choose> <xsl:when test="@format"> <xsp:expr><xsl:call-template name="get-resultset"/>.getDate(<xsl:call-template name="get-column"/>) == null ? "" : new SimpleDateFormat("<xsl:value-of select="@format"/>").format(<xsl:call-template name="get-resultset"/>.getDate(<xsl:call-template name="get-column"/>))</xsp:expr> @@ -803,7 +862,7 @@ </xsl:template> <xspdoc:desc>returns the value of the given column as a time. if a format attribute exists, its value is taken to be a date format string as defined in java.text.SimpleDateFormat, and the result is formatted accordingly.</xspdoc:desc> -<xsl:template match="esql:row-results//esql:get-time"> +<xsl:template match="esql:row-results//esql:get-time|esql:call-results//esql:get-time"> <xsl:choose> <xsl:when test="@format"> <xsp:expr><xsl:call-template name="get-resultset"/>.getTime(<xsl:call-template name="get-column"/>) == null ? "" : new SimpleDateFormat("<xsl:value-of select="@format"/>").format(<xsl:call-template name="get-resultset"/>.getTime(<xsl:call-template name="get-column"/>))</xsp:expr> @@ -815,7 +874,7 @@ </xsl:template> <xspdoc:desc>returns the value of the given column as a timestamp. if a format attribute exists, its value is taken to be a date format string as defined in java.text.SimpleDateFormat, and the result is formatted accordingly.</xspdoc:desc> -<xsl:template match="esql:row-results//esql:get-timestamp"> +<xsl:template match="esql:row-results//esql:get-timestamp|esql:call-results//esql:get-timestamp"> <xsl:choose> <xsl:when test="@format"> <xsp:expr><xsl:call-template name="get-resultset"/>.getTimestamp(<xsl:call-template name="get-column"/>) == null ? "" : new SimpleDateFormat("<xsl:value-of select="@format"/>").format(<xsl:call-template name="get-resultset"/>.getTimestamp(<xsl:call-template name="get-column"/>))</xsp:expr> @@ -827,12 +886,12 @@ </xsl:template> <xspdoc:desc>returns the value of the given column as true or false</xspdoc:desc> -<xsl:template match="esql:row-results//esql:get-boolean"> +<xsl:template match="esql:row-results//esql:get-boolean|esql:call-results//esql:get-boolean"> <xsp:expr><xsl:call-template name="get-resultset"/>.getBoolean(<xsl:call-template name="get-column"/>)</xsp:expr> </xsl:template> <xspdoc:desc>returns the value of the given column as a double. if a format attribute exists, its value is taken to be a decimal format string as defined in java.text.DecimalFormat, and the result is formatted accordingly.</xspdoc:desc> -<xsl:template match="esql:row-results//esql:get-double"> +<xsl:template match="esql:row-results//esql:get-double|esql:call-results//esql:get-double"> <xsl:choose> <xsl:when test="@format"> <xsp:expr>new DecimalFormat("<xsl:value-of select="@format"/>").format(new Double(<xsl:call-template name="get-resultset"/>.getDouble(<xsl:call-template name="get-column"/>)))</xsp:expr> @@ -844,7 +903,7 @@ </xsl:template> <xspdoc:desc>returns the value of the given column as a float. if a format attribute exists, its value is taken to be a decimal format string as defined in java.text.DecimalFormat, and the result is formatted accordingly.</xspdoc:desc> -<xsl:template match="esql:row-results//esql:get-float"> +<xsl:template match="esql:row-results//esql:get-float|esql:call-results//esql:get-float"> <xsl:choose> <xsl:when test="@format"> <xsp:expr>new DecimalFormat("<xsl:value-of select="@format"/>").format(new Float(<xsl:call-template name="get-resultset"/>.getFloat(<xsl:call-template name="get-column"/>)))</xsp:expr> @@ -861,37 +920,37 @@ </xsl:template> <xspdoc:desc>returns the value of the given column as an object</xspdoc:desc> -<xsl:template match="esql:row-results//esql:get-object"> +<xsl:template match="esql:row-results//esql:get-object|esql:call-results//esql:get-object"> <xsp:expr><xsl:call-template name="get-resultset"/>.getObject(<xsl:call-template name="get-column"/>)</xsp:expr> </xsl:template> <xspdoc:desc>returns the value of the given column as an array</xspdoc:desc> -<xsl:template match="esql:row-results//esql:get-array"> +<xsl:template match="esql:row-results//esql:get-array|esql:call-results//esql:get-array"> <xsp:expr><xsl:call-template name="get-resultset"/>.getArray(<xsl:call-template name="get-column"/>)</xsp:expr> </xsl:template> <xspdoc:desc>returns the value of the given column as a struct</xspdoc:desc> -<xsl:template match="esql:row-results//esql:get-struct"> +<xsl:template match="esql:row-results//esql:get-struct|esql:call-results//esql:get-struct"> <xsp:expr>(Struct) <xsl:call-template name="get-resultset"/>.getObject(<xsl:call-template name="get-column"/>)</xsp:expr> </xsl:template> <xspdoc:desc>returns the value of the given column as an integer</xspdoc:desc> -<xsl:template match="esql:row-results//esql:get-int"> +<xsl:template match="esql:row-results//esql:get-int|esql:call-results//esql:get-int"> <xsp:expr><xsl:call-template name="get-resultset"/>.getInt(<xsl:call-template name="get-column"/>)</xsp:expr> </xsl:template> <xspdoc:desc>returns the value of the given column as a long</xspdoc:desc> -<xsl:template match="esql:row-results//esql:get-long"> +<xsl:template match="esql:row-results//esql:get-long|esql:call-results//esql:get-long"> <xsp:expr><xsl:call-template name="get-resultset"/>.getLong(<xsl:call-template name="get-column"/>)</xsp:expr> </xsl:template> <xspdoc:desc>returns the value of the given column as a short</xspdoc:desc> -<xsl:template match="esql:row-results//esql:get-short"> +<xsl:template match="esql:row-results//esql:get-short|esql:call-results//esql:get-short"> <xsp:expr><xsl:call-template name="get-resultset"/>.getShort(<xsl:call-template name="get-column"/>)</xsp:expr> </xsl:template> <xspdoc:desc>returns the value of the given column as a clob</xspdoc:desc> -<xsl:template match="esql:row-results//esql:get-ascii"> +<xsl:template match="esql:row-results//esql:get-ascii|esql:call-results//esql:get-ascii"> <xsp:expr>EsqlHelper.getAscii(<xsl:call-template name="get-resultset"/>, <xsl:call-template name="get-column"/>)</xsp:expr> </xsl:template> @@ -899,7 +958,7 @@ The fragment is parsed by the default xsp parser and the document element is returned. If a root attribute exists, its value is taken to be the name of an element to wrap around the contents of the fragment before parsing.</xspdoc:desc> -<xsl:template match="esql:row-results//esql:get-xml"> +<xsl:template match="esql:row-results//esql:get-xml|esql:call-results//esql:get-xml"> <xsl:variable name="content"> <xsl:choose> <xsl:when test="@root"> @@ -972,27 +1031,27 @@ </xsl:template> <xspdoc:desc>returns the position of the current row in the result set</xspdoc:desc> -<xsl:template match="esql:row-results//esql:get-row-position|esql:results//esql:get-row-position"> +<xsl:template match="esql:row-results//esql:get-row-position|esql:results//esql:get-row-position|esql:call-results//esql:get-row-position"> <xsp:expr>_esql_query.getCurrentRow()</xsp:expr> </xsl:template> <xspdoc:desc>returns the name of the given column. the column mus tbe specified by number, not name.</xspdoc:desc> -<xsl:template match="esql:row-results//esql:get-column-name"> +<xsl:template match="esql:row-results//esql:get-column-name|esql:call-results//esql:get-column-name"> <xsp:expr><xsl:call-template name="get-resultset"/>.getMetaData().getColumnName(<xsl:call-template name="get-column"/>)</xsp:expr> </xsl:template> <xspdoc:desc>returns the label of the given column. the column mus tbe specified by number, not name.</xspdoc:desc> -<xsl:template match="esql:row-results//esql:get-column-label"> +<xsl:template match="esql:row-results//esql:get-column-label|esql:call-results//esql:get-column-label"> <xsp:expr><xsl:call-template name="get-resultset"/>.getMetaData().getColumnLabel(<xsl:call-template name="get-column"/>)</xsp:expr> </xsl:template> <xspdoc:desc>returns the name of the type of the given column. the column must be specified by number, not name.</xspdoc:desc> -<xsl:template match="esql:row-results//esql:get-column-type-name"> +<xsl:template match="esql:row-results//esql:get-column-type-name|esql:call-results//esql:get-column-type-name"> <xsp:expr><xsl:call-template name="get-resultset"/>.getMetaData().getColumnTypeName(<xsl:call-template name="get-column"/>)</xsp:expr> </xsl:template> <xspdoc:desc>returns the type of the given column as int. the column must be specified by number, not name.</xspdoc:desc> -<xsl:template match="esql:row-results//esql:get-column-type"> +<xsl:template match="esql:row-results//esql:get-column-type|esql:call-results//esql:get-column-type"> <xsp:expr><xsl:call-template name="get-resultset"/>.getMetaData().getColumnType(<xsl:call-template name="get-column"/>)</xsp:expr> </xsl:template> @@ -1001,6 +1060,40 @@ <xsp:expr>((<xsl:call-template name="get-resultset"/>.getObject("<xsl:value-of select="@column"/>") == null) || <xsl:call-template name="get-resultset"/>.wasNull())</xsp:expr> </xsl:template> +<xspdoc:desc>creates a nested query like block that uses the result set obtained from a column as current result set. Only row-results and no-results are supported as nested elements (i.e. more-results is not supported).</xspdoc:desc> +<xsl:template match="esql:row-results//esql:results[@from-column]|esql:call-results//esql:results[@from-column]" priority="2"> +<xsp:logic> + // nested result set + if (_esql_query != null) { + _esql_queries.push(_esql_query); + } + _esql_query = new EsqlQuery((ResultSet) <xsl:call-template name="get-resultset"/>.getObject(<xsl:value-of select="@from-column"/>)); + { + if (_esql_query.hasResultSet()) { + do { + _esql_query.getResultRows(); + + if (_esql_query.nextRow()) { + <xsl:apply-templates select="esql:row-results"/> + } + else { + <xsl:apply-templates select="esql:no-results"/> + } + _esql_query.getResultSet().close(); + + } while(_esql_query.getMoreResults()); + } else { + <xsl:apply-templates select="esql:no-results"/> + } + } + if (_esql_queries.empty()) { + _esql_query = null; + } else { + _esql_query = (EsqlQuery)_esql_queries.pop(); + } + </xsp:logic> +</xsl:template> + <xspdoc:desc>returns the message of the current exception</xspdoc:desc> <xsl:template match="esql:error-results//esql:get-message"> <xsp:expr>_esql_exception.getMessage()</xsp:expr> @@ -1017,7 +1110,7 @@ </xsl:template> <xsl:template name="get-resultset"> - <xsl:call-template name="get-query"/><xsl:text>.getResultSet()</xsl:text> + <xsl:call-template name="get-query"/><xsl:choose><xsl:when test="@from-call='yes' or @from-call='true'"><xsl:text>.getCallableStatement()</xsl:text></xsl:when><xsl:otherwise><xsl:text>.getResultSet()</xsl:text></xsl:otherwise></xsl:choose> </xsl:template> <xsl:template name="get-query"> @@ -1087,6 +1180,27 @@ </xsl:otherwise> </xsl:choose> </xsl:template> + +<xsl:template name="get-Sql-Type"> + <xsl:param name="type"/> + <xsl:choose> + <!-- just do the 'unusual' mappings --> + <xsl:when test="$type='Byte'">TINYINT</xsl:when> + <xsl:when test="$type='Short'">SMALLINT</xsl:when> + <xsl:when test="$type='Int'">INTEGER</xsl:when> + <xsl:when test="$type='Long'">BIGINT</xsl:when> + <xsl:when test="$type='Float'">REAL</xsl:when> + <xsl:when test="$type='BigDecimal'">DECIMAL</xsl:when> + <xsl:when test="$type='Boolean'">BIT</xsl:when> + <xsl:when test="$type='String'">VARCHAR</xsl:when> + <xsl:when test="$type='Bytes'">BINARY</xsl:when> + <xsl:when test="$type='AsciiStream'">LONGVARCHAR</xsl:when> + <xsl:when test="$type='UnicodeStream'">LONGVARCHAR</xsl:when> + <xsl:when test="$type='BinaryStream'">VARBINARY</xsl:when> + <xsl:otherwise><xsl:value-of select="translate(@type,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/></xsl:otherwise> + </xsl:choose> +</xsl:template> + <!-- Break on error. 1.2 +57 -0 xml-cocoon2/src/documentation/xdocs/userdocs/xsp/esql.xml Index: esql.xml =================================================================== RCS file: /home/cvs/xml-cocoon2/src/documentation/xdocs/userdocs/xsp/esql.xml,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- esql.xml 3 Jan 2002 12:31:06 -0000 1.1 +++ esql.xml 31 Jan 2002 16:11:33 -0000 1.2 @@ -128,6 +128,63 @@ </esql:execute-query>]]> </source> + <s2 title="Stored Procedure Support"> + <p>In order to use stored procedures replace + <code><esql:query/></code> with + <code><esql:call/></code>, use either DBMS specific syntax or + JDBC escape syntax <code>{? = foo(?)}</code>. If your jdbc driver + requires to use the <code>executeQuery()</code> method instead of + the <code>execute()</code> method (like e.g. INFORMIX does), set + <code>needs-query="true"</code> attribute.</p> + + <p>If a result set is returned through the (only) return parameter of + a stored procedure, e.g. <code>resultset-from-object="1"</code> as attribute + to <code><esql:call/></code>to automatically use this result + set. For a more general alternative see further below.</p> + + <p>Parameters for a stored procedure call may be of + <code>direction="in|out|inout"</code> with the usual JDBC meaning. In + addition a <code>type</code> needs to be supplied as well. This would + be the same "XXX" as used in a <code>get-XXX</code> JDBC-method + call.</p> + + <p><code><esql:call-results/></code> (child of + <code><esql:execute-query/></code>) may contain code that will + always be executed whether the query returned a result or not. For + example most stored procedures will not return a result set but + several out parameters.</p> + + <p>all <code><esql:get-xxx/></code> tags accept new attribute + <code>from-call="yes"</code> to indicate that the value is retrieved + from the CallableStatement rather than the current + ResultSet. Obviously, this only works after a call to a stored + procedure.</p> + + <p>Retrieve a ResultSet from any column and use it like the result of a + nested query by e.g. <code><esql:results + from-column="1"/></code>. Of course the column needs to return a + result that is castable to ResultSet. Supported child elements are + <code><esql:row-results/></code> and + <code><esql:no-results/></code>. Otherwise it behaves + exactly like nesting queries. Thus the <code>ancestor</code> + attribute can be used to access e.g. the original query.</p> + + + <p>Example:</p> + <source> +<![CDATA[ + <esql:call>{? = foo(<esql:parameter direction="in" type="Int"><xsp:expr>1</xsp:expr></esql:parameter>)}</esql:call> + <esql:call-results> + <esql:results from-column="1" from-call="true"> + <esql:row-results> + <esql:get-string column="1"/> + </esql:row-results> + </esql:results> + </esql:call-results> +]]> + </source> + </s2> + <p>The ultimate reference, is of course the source code, which is an XSLT logicsheet contained in the file <code>src/org/apache/cocoon/components/language/markup/xsp/java/esql.xsl</code></p>
---------------------------------------------------------------------- In case of troubles, e-mail: [EMAIL PROTECTED] To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]