<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>OpenText Analytics Database 26.2.x – Stored procedures</title>
    <link>/en/extending/stored-procedures/</link>
    <description>Recent content in Stored procedures on OpenText Analytics Database 26.2.x</description>
    <generator>Hugo -- gohugo.io</generator>
    
	  <atom:link href="/en/extending/stored-procedures/index.xml" rel="self" type="application/rss+xml" />
    
    
      
        
      
    
    
    <item>
      <title>Extending: PL/vSQL</title>
      <link>/en/extending/stored-procedures/plvsql/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/extending/stored-procedures/plvsql/</guid>
      <description>
        
        
        &lt;p&gt;PL/vSQL is a powerful and expressive procedural language for creating reusable procedures, manipulating data, and simplifying otherwise complex database routines.&lt;/p&gt;
&lt;p&gt;OpenText™ Analytics Database PL/vSQL is largely compatible with PostgreSQL PL/pgSQL, with minor semantic differences. For details on migrating your &lt;a href=&#34;https://www.postgresql.org/docs/current/plpgsql.html&#34;&gt;PostgreSQL PL/pgSQL&lt;/a&gt; stored procedures to the database, see &lt;a href=&#34;../../../en/extending/stored-procedures/plvsql/plpgsql-to-plvsql-migration/#&#34;&gt;PL/pgSQL to PL/vSQL migration guide&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For real-world, practical examples of PL/vSQL usage, see &lt;a href=&#34;../../../en/extending/stored-procedures/stored-procedures-use-cases-and-examples/#&#34;&gt;Stored procedures: use cases and examples&lt;/a&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Extending: Parameter modes</title>
      <link>/en/extending/stored-procedures/parameter-modes/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/extending/stored-procedures/parameter-modes/</guid>
      <description>
        
        
        &lt;p&gt;Each formal parameter of a stored procedure can be set to one of the following parameter modes. If unspecified, the parameter is set to IN:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IN: An input parameter. The caller uses this to pass arguments to the stored procedure.&lt;/li&gt;
&lt;li&gt;OUT: An output parameter. The stored procedure returns values as a result set, the columns of which are identified by the name of the output parameter.&lt;/li&gt;
&lt;li&gt;INOUT: An input and output parameter. The caller can both pass an argument to the stored procedure and retrieve it from the result set.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;function-signatures-and-overloading&#34;&gt;Function signatures and overloading&lt;/h2&gt;
&lt;p&gt;A function&#39;s signature is defined by the function&#39;s name and input parameter (IN and INOUT) types. You cannot &lt;a href=&#34;../../../en/sql-reference/statements/create-statements/create-procedure-stored/&#34;&gt;create&lt;/a&gt; two stored procedures with the same function signature.&lt;/p&gt;
&lt;p&gt;An overloaded function is a set of functions that share the same name but have different input parameters. This can be useful in cases where a function needs to operate on multiple types. For example, the two functions &lt;code&gt;find_average(int, int, int)&lt;/code&gt; and &lt;code&gt;find_average(float, float, float)&lt;/code&gt; describe the overloaded function &lt;code&gt;find_average()&lt;/code&gt; that operates on integers and floats.&lt;/p&gt;
&lt;p&gt;When an overloaded procedure is &lt;a href=&#34;../../../en/extending/stored-procedures/executing-stored-procedures/&#34;&gt;called&lt;/a&gt;, OpenText™ Analytics Database runs the procedure whose signature matches the types of the arguments passed in the invocation.&lt;/p&gt;
&lt;p&gt;The example procedures below use RAISE NOTICE for informational messages. For details, see &lt;a href=&#34;../../../en/extending/stored-procedures/plvsql/errors-and-diagnostics/#&#34;&gt;Errors and diagnostics&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;in&#34;&gt;IN&lt;/h2&gt;
&lt;p&gt;IN parameters specify the name and type of an argument. For example, the caller of this procedure must pass in an INT and a VARCHAR value:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;PROCEDURE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;raiseXY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;IN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;INT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;VARCHAR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;LANGUAGE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PLvSQL&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;$$&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;BEGIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RAISE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NOTICE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;x = %&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RAISE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NOTICE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;y = %&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;END&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;$$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;CALL&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;raiseXY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;some string&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NOTICE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2005&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NOTICE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2005&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;some&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;out&#34;&gt;OUT&lt;/h2&gt;
&lt;p&gt;OUT parameters specify the name and type of a return value. When the procedure runs, the OUT parameter is added to the scope of the stored procedure as a variable. This variable&#39;s value is initialized as NULL and is returned in a result set after execution:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;PROCEDURE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sum_procedure&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;IN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;INT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;IN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;INT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;OUT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;INT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;LANGUAGE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PLvSQL&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;$$&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;BEGIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RAISE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NOTICE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;This procedure returns the sum of x and y as z:&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;END&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;$$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;CALL&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sum_procedure&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;38&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;19&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NOTICE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2005&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;This&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;procedure&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;returns&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;the&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;sum&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;of&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;and&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;as&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;----
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;57&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;row&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;inout&#34;&gt;INOUT&lt;/h2&gt;
&lt;p&gt;INOUT parameters specify the name and type of both an input value and return value. When the procedure runs, the IN/OUT parameter is initialized to the value passed in by the caller and is returned in a result set after execution:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;PROCEDURE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INOUT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;INT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;LANGUAGE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PLvSQL&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;$$&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;BEGIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RAISE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NOTICE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;This procedure returns its input:&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;END&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;$$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;CALL&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;19&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NOTICE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2005&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;This&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;procedure&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;returns&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;its&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;----
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;19&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;row&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
      </description>
    </item>
    
    <item>
      <title>Extending: Executing stored procedures</title>
      <link>/en/extending/stored-procedures/executing-stored-procedures/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/extending/stored-procedures/executing-stored-procedures/</guid>
      <description>
        
        
        &lt;p&gt;If you have EXECUTE privileges on a stored procedure, you can execute it with a CALL statement that specifies the procedure and its &lt;a href=&#34;../../../en/extending/stored-procedures/parameter-modes/&#34;&gt;IN&lt;/a&gt; arguments.&lt;/p&gt;
&lt;h2 id=&#34;syntax&#34;&gt;Syntax&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;CALL &lt;span class=&#34;code-variable&#34;&gt;stored_procedure_name&lt;/span&gt;();
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For example, the stored procedure &lt;code&gt;raiseXY()&lt;/code&gt; is defined as:&lt;/p&gt;
&lt;p&gt;The following procedure echoes its inputs as a result set:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;PROCEDURE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;echo_int_varchar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INOUT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;INT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INOUT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;VARCHAR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;LANGUAGE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PLvSQL&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;$$&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;BEGIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RAISE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NOTICE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;This procedure outputs a result set of its inputs:&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;END&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;$$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;CALL&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;echo_int_varchar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;a string&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NOTICE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2005&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;This&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;procedure&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;outputs&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;of&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;its&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inputs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;---+----------
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;row&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can execute an anonymous (unnamed) procedure with &lt;a href=&#34;../../../en/sql-reference/statements/do/#&#34;&gt;DO&lt;/a&gt;. This requires no privileges:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; DO $$
BEGIN
    RAISE NOTICE &amp;#39;% ran an anonymous procedure&amp;#39;, current_user();
END;
$$;

NOTICE 2005:  Bob ran an anonymous procedure
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;transaction-semantics&#34;&gt;Transaction semantics&lt;/h2&gt;
&lt;p&gt;A procedure takes on one of two types depending on how it&#39;s called:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;../../../en/extending/stored-procedures/plvsql/scope-and-structure/#nested-stored-procedures&#34;&gt;Nested&lt;/a&gt;: A procedure that is called in the body of some other procedure.&lt;/li&gt;
&lt;li&gt;Top-level: A non-nested stored procedure. A procedure called directly by a user (with either &lt;a href=&#34;../../../en/sql-reference/statements/call/#&#34;&gt;CALL&lt;/a&gt; or &lt;a href=&#34;../../../en/sql-reference/statements/do/#&#34;&gt;DO&lt;/a&gt;) or &lt;a href=&#34;../../../en/extending/stored-procedures/executing-stored-procedures/triggers/&#34;&gt;trigger&lt;/a&gt; is top-level.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example, if &lt;code&gt;A()&lt;/code&gt; calls &lt;code&gt;B()&lt;/code&gt;, then &lt;code&gt;A()&lt;/code&gt; would be a top-level procedure and &lt;code&gt;B()&lt;/code&gt; would be a nested procedure in the context of &lt;code&gt;A()&lt;/code&gt;&#39;s execution. If &lt;code&gt;B()&lt;/code&gt; is called directly by the user or a trigger, it would be a top-level procedure.&lt;/p&gt;
&lt;p&gt;Similarly, if some procedure &lt;code&gt;C()&lt;/code&gt; calls &lt;code&gt;A()&lt;/code&gt;, then &lt;code&gt;C()&lt;/code&gt; would be the top-level procedure and &lt;code&gt;A()&lt;/code&gt; and &lt;code&gt;B()&lt;/code&gt; would both be nested procedures in the context of &lt;code&gt;C()&lt;/code&gt;&#39;s execution.&lt;/p&gt;
&lt;h3 id=&#34;automatic-commits&#34;&gt;Automatic commits&lt;/h3&gt;
&lt;p&gt;Executing a top-level procedure opens a new transaction, which is committed if its execution (including those of any nested procedures) succeeds and &lt;a href=&#34;../../../en/sql-reference/statements/rollback/&#34;&gt;rolled back&lt;/a&gt; otherwise. If an ongoing transaction exists in the current session before execution, OpenText™ Analytics Database commits that transaction before calling the procedure. Nested procedures do not start their own transactions.&lt;/p&gt;

&lt;div class=&#34;alert admonition note&#34; role=&#34;alert&#34;&gt;
&lt;h4 class=&#34;admonition-head&#34;&gt;Note&lt;/h4&gt;

While triggers also execute top-level stored procedures and therefore also perform a pre-execution commit, triggers execute in their own session, so the commit does not affect the ongoing transactions of other sessions.

&lt;/div&gt;
&lt;p&gt;For example, when &lt;code&gt;A()&lt;/code&gt; is called, the following occurs:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Before executing &lt;code&gt;A()&lt;/code&gt;, commit any ongoing transaction.&lt;/li&gt;
&lt;li&gt;Start a new transaction for the execution of &lt;code&gt;A()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Execute &lt;code&gt;A()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;A()&lt;/code&gt; calls &lt;code&gt;B()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;A()&lt;/code&gt; and &lt;code&gt;B()&lt;/code&gt; both successfully execute without errors, commit the transaction. Otherwise, any changes performed by &lt;code&gt;A()&lt;/code&gt; and &lt;code&gt;B()&lt;/code&gt; are rolled back.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;manual-commits&#34;&gt;Manual commits&lt;/h3&gt;
&lt;p&gt;You can also manually commit changes in the middle of a stored procedure. If execution fails after the commit, the committed changes persist even after the automatic rollback.&lt;/p&gt;
&lt;p&gt;In this example, &lt;code&gt;manual_commit()&lt;/code&gt; inserts two values into a table and then commits. The third insert attempts to insert a CHAR into an INT column, which causes the stored procedure to fail and triggers an automatic rollback. This rollback does not affect the first two inserts because they were manually committed:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;TABLE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;numbers&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;INT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;PROCEDURE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;manualcommit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;$$&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;BEGIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PERFORM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INSERT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INTO&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;numbers&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;VALUES&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PERFORM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INSERT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INTO&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;numbers&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;VALUES&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PERFORM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;COMMIT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PERFORM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INSERT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INTO&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;numbers&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;VALUES&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;END&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;$$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;CALL&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;manualcommit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ERROR&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3681&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Invalid&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;syntax&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;integer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CONTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vSQL&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;procedure&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;manualcommit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;line&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;at&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;SQL&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;numbers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;rows&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;session-semantics&#34;&gt;Session semantics&lt;/h2&gt;
&lt;p&gt;Operations that modify the session persist after execution of the stored procedure, including &lt;a href=&#34;../../../en/sql-reference/statements/alter-statements/alter-session/#&#34;&gt;ALTER SESSION&lt;/a&gt; and &lt;a href=&#34;../../../en/sql-reference/statements/set-statements/#&#34;&gt;SET statements&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;../../../en/extending/stored-procedures/executing-stored-procedures/triggers/&#34;&gt;Triggers&lt;/a&gt; execute in their own, isolated session.&lt;/p&gt;
&lt;h2 id=&#34;limiting-runtime&#34;&gt;Limiting runtime&lt;/h2&gt;
&lt;p&gt;You can set the maximum runtime of a procedure with session parameter RUNTIMECAP.&lt;/p&gt;
&lt;p&gt;This example sets the runtime of all stored procedures to one second for duration of session and runs an anonymous procedure with an &lt;a href=&#34;../../../en/extending/stored-procedures/plvsql/control-flow/#loop&#34;&gt;infinite loop&lt;/a&gt;. OpenText™ Analytics Database terminates the procedure after it runs for more than one second:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SET SESSION RUNTIMECAP &amp;#39;1 SECOND&amp;#39;;

=&amp;gt; DO $$
BEGIN
    LOOP
    END LOOP;
END;
$$;

ERROR 0:  Query exceeded maximum runtime
HINT:  Change the maximum runtime using SET SESSION RUNTIMECAP
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;execution-security-and-privileges&#34;&gt;Execution security and privileges&lt;/h2&gt;
&lt;p&gt;By default, stored procedures execute with the privileges of the caller (invoker), so callers must have the necessary privileges on the catalog objects accessed by the stored procedure. You can allow callers to execute the procedure with the privileges, &lt;a href=&#34;../../../en/sql-reference/statements/set-statements/set-role/&#34;&gt;default roles&lt;/a&gt;, &lt;a href=&#34;../../../en/admin/configuring-db/config-parameter-management/viewing-config-parameter-values/&#34;&gt;user parameters&lt;/a&gt;, and &lt;a href=&#34;../../../en/admin/managing-db/managing-workloads/resource-pool-architecture/user-resource-allocation/&#34;&gt;user attributes&lt;/a&gt; (RESOURCE_POOL, MEMORY_CAP_KB, TEMP_SPACE_CAP_KB, RUNTIMECAP) of the definer by specifying &lt;a href=&#34;../../../en/sql-reference/statements/create-statements/create-procedure-stored/&#34;&gt; DEFINER for the SECURITY option&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For example, the following procedure inserts a value into table &lt;code&gt;s1.t1&lt;/code&gt;. If the DEFINER has the required privileges (USAGE on the schema and INSERT on table), this requirement is waived for callers.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; CREATE PROCEDURE insert_into_s1_t1(IN x int, IN y int)
LANGUAGE PLvSQL
SECURITY DEFINER AS $$
BEGIN
    PERFORM INSERT INTO s1.t1 VALUES(x,y);
END;
$$;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A procedure with SECURITY DEFINER effectively executes the procedure as that user, so changes to the database appear to be performed by the procedure&#39;s definer rather than its caller.

&lt;div class=&#34;admonition caution&#34; role=&#34;alert&#34;&gt;
&lt;h4 class=&#34;admonition-head&#34;&gt;Caution&lt;/h4&gt;

Improper use of SECURITY DEFINER can lead to the &lt;a href=&#34;https://en.wikipedia.org/wiki/Confused_deputy_problem&#34;&gt;confused deputy problem&lt;/a&gt; and introduce vulnerabilities into your system like SQL injection.

&lt;/div&gt;&lt;/p&gt;

&lt;h3 id=&#34;execution-privileges-for-nested-stored-procedures&#34;&gt;Execution privileges for nested stored procedures&lt;/h3&gt;
&lt;p&gt;A stored procedure cannot call stored procedures that require additional privileges. For example, if a stored procedure executes with privileges A, B, and C, it cannot call a stored procedure that requires privileges C, D, and E.&lt;/p&gt;
&lt;p&gt;For details on nested stored procedures, see &lt;a href=&#34;../../../en/extending/stored-procedures/plvsql/scope-and-structure/#&#34;&gt;Scope and structure&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;examples&#34;&gt;Examples&lt;/h3&gt;
&lt;p&gt;In this example, this table:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;records(i INT, updated_date TIMESTAMP DEFAULT sysdate, updated_by VARCHAR(128) DEFAULT current_user())
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Contains the following content:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT * FROM records;
 i |        updated_date        | updated_by
---+----------------------------+------------
 1 | 2021-08-27 15:54:05.709044 | Bob
 2 | 2021-08-27 15:54:07.051154 | Bob
 3 | 2021-08-27 15:54:08.301704 | Bob
(3 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Bob creates a procedure to update the table and uses the SECURITY DEFINER option and grants EXECUTE on the procedure to Alice. Alice can now use the procedure to update the table without any additional privileges:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; GRANT EXECUTE ON PROCEDURE update_records(int,int) to Alice;
GRANT PRIVILEGE

=&amp;gt; \c - Alice
You are now connected as user &amp;#34;Alice&amp;#34;.

=&amp;gt; CALL update_records(99,1);
 update_records
---------------
             0
(1 row)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Because calls to &lt;code&gt;update_records()&lt;/code&gt; effectively run the procedure as Bob, Bob is listed as the updater of the table rather than Alice:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT * FROM records;
 i  |        updated_date        | updated_by
----+----------------------------+------------
 99 | 2021-08-27 15:55:42.936404 | Bob
  2 | 2021-08-27 15:54:07.051154 | Bob
  3 | 2021-08-27 15:54:08.301704 | Bob
(3 rows)
&lt;/code&gt;&lt;/pre&gt;

      </description>
    </item>
    
    <item>
      <title>Extending: Altering stored procedures</title>
      <link>/en/extending/stored-procedures/altering-stored-procedures/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/extending/stored-procedures/altering-stored-procedures/</guid>
      <description>
        
        
        &lt;p&gt;You can alter a stored procedure and retain its grants with &lt;a href=&#34;../../../en/sql-reference/statements/alter-statements/alter-procedure-stored/&#34;&gt;ALTER PROCEDURE&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;examples&#34;&gt;Examples&lt;/h2&gt;
&lt;p&gt;The examples below use the following procedure:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; CREATE PROCEDURE echo_integer(IN x int) LANGUAGE PLvSQL AS $$
BEGIN
    RAISE INFO &amp;#39;x is %&amp;#39;, x;
END;
$$;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;By default, stored procedures execute with the privileges of the caller (invoker), so callers must have the necessary privileges on the catalog objects accessed by the stored procedure. You can allow callers to execute the procedure with the privileges, &lt;a href=&#34;../../../en/sql-reference/statements/set-statements/set-role/&#34;&gt;default roles&lt;/a&gt;, &lt;a href=&#34;../../../en/admin/configuring-db/config-parameter-management/viewing-config-parameter-values/&#34;&gt;user parameters&lt;/a&gt;, and &lt;a href=&#34;../../../en/admin/managing-db/managing-workloads/resource-pool-architecture/user-resource-allocation/&#34;&gt;user attributes&lt;/a&gt; (RESOURCE_POOL, MEMORY_CAP_KB, TEMP_SPACE_CAP_KB, RUNTIMECAP) of the definer by specifying &lt;a href=&#34;../../../en/sql-reference/statements/create-statements/create-procedure-stored/&#34;&gt; DEFINER for the SECURITY option&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To &lt;a href=&#34;../../../en/sql-reference/statements/call/&#34;&gt;execute&lt;/a&gt; the procedure with privileges of the...&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Definer (owner):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; ALTER PROCEDURE echo_integer(int) SECURITY DEFINER;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Invoker:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; ALTER PROCEDURE echo_integer(int) SECURITY INVOKER;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To change a procedure&#39;s source code:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; ALTER PROCEDURE echo_integer(int) SOURCE TO $$
    BEGIN
        RAISE INFO &amp;#39;the integer is: %&amp;#39;, x;
    END;
$$;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To change a procedure&#39;s owner (definer):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; ALTER PROCEDURE echo_integer(int) OWNER TO u1;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To change a procedure&#39;s schema:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; ALTER PROCEDURE echo_integer(int) SET SCHEMA s1;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To rename a procedure:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; ALTER PROCEDURE echo_integer(int) RENAME TO echo_int;
&lt;/code&gt;&lt;/pre&gt;
      </description>
    </item>
    
    <item>
      <title>Extending: Stored procedures: use cases and examples</title>
      <link>/en/extending/stored-procedures/stored-procedures-use-cases-and-examples/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/extending/stored-procedures/stored-procedures-use-cases-and-examples/</guid>
      <description>
        
        
        &lt;p&gt;Stored procedures are best suited for &lt;a href=&#34;../../../en/extending/stored-procedures/&#34;&gt;complex, analytical workflows&lt;/a&gt; rather than small, transaction-heavy ones. Some recommended use cases include information lifecycle management (ILM) activities like extract, transform, and load (ETL), and data preparation for more complex analytical tasks like machine learning. For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Swapping partitions according to age&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Exporting data at end-of-life and dropping the partitions&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Saving inputs, outputs, and metadata from a machine learning model (e.g. who ran the model, the version of the model, how many times the model was run, who received the results, etc.) for auditing purposes&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;searching-for-a-value&#34;&gt;Searching for a value&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;find_my_value()&lt;/code&gt; procedure searches for a user-specified value in any table column in a given schema and stores the locations of instances of the value in a user-specified table:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; CREATE PROCEDURE find_my_value(p_table_schema VARCHAR(128), p_search_value VARCHAR(1000), p_results_schema VARCHAR(128), p_results_table VARCHAR(128)) AS $$
DECLARE
    sql_cmd VARCHAR(65000);
    sql_cmd_result VARCHAR(65000);
    results VARCHAR(65000);
BEGIN
    IF p_table_schema IS NULL OR p_table_schema = &amp;#39;&amp;#39; OR
        p_search_value IS NULL OR p_search_value = &amp;#39;&amp;#39; OR
        p_results_schema IS NULL OR p_results_schema = &amp;#39;&amp;#39; OR
        p_results_table IS NULL OR p_results_table = &amp;#39;&amp;#39; THEN
        RAISE EXCEPTION &amp;#39;Please provide a schema to search, a search value, a results table schema, and a results table name.&amp;#39;;
        RETURN;
    END IF;

    sql_cmd := &amp;#39;CREATE TABLE IF NOT EXISTS &amp;#39; || QUOTE_IDENT(p_results_schema) || &amp;#39;.&amp;#39; || QUOTE_IDENT(p_results_table) ||
        &amp;#39;(found_timestamp TIMESTAMP, found_value VARCHAR(1000), table_name VARCHAR(128), column_name VARCHAR(128));&amp;#39;;

    sql_cmd_result := EXECUTE &amp;#39;SELECT LISTAGG(c USING PARAMETERS max_length=1000000, separator=&amp;#39;&amp;#39; &amp;#39;&amp;#39;)
        FROM (SELECT &amp;#39;&amp;#39;
        (SELECT &amp;#39;&amp;#39;&amp;#39;&amp;#39;&amp;#39;&amp;#39; || NOW() || &amp;#39;&amp;#39;&amp;#39;&amp;#39;&amp;#39;&amp;#39;::TIMESTAMP , &amp;#39;&amp;#39;&amp;#39;&amp;#39;&amp;#39; || QUOTE_IDENT(p_search_value) || &amp;#39;&amp;#39;&amp;#39;&amp;#39;&amp;#39;,&amp;#39;&amp;#39;&amp;#39;&amp;#39;&amp;#39;&amp;#39; || table_name || &amp;#39;&amp;#39;&amp;#39;&amp;#39;&amp;#39;&amp;#39;, &amp;#39;&amp;#39;&amp;#39;&amp;#39;&amp;#39;&amp;#39; || column_name || &amp;#39;&amp;#39;&amp;#39;&amp;#39;&amp;#39;&amp;#39;
            FROM &amp;#39;&amp;#39; || table_schema || &amp;#39;&amp;#39;.&amp;#39;&amp;#39; || table_name || &amp;#39;&amp;#39;
            WHERE &amp;#39;&amp;#39; || column_name || &amp;#39;&amp;#39;::&amp;#39;&amp;#39; ||
            CASE
                WHEN data_type_id IN (17, 115, 116, 117) THEN data_type
                ELSE &amp;#39;&amp;#39;VARCHAR(&amp;#39;&amp;#39; || LENGTH(&amp;#39;&amp;#39;&amp;#39; || QUOTE_IDENT(p_search_value)|| &amp;#39;&amp;#39;&amp;#39;) || &amp;#39;&amp;#39;)&amp;#39;&amp;#39; END || &amp;#39;&amp;#39; = &amp;#39;&amp;#39;&amp;#39;&amp;#39;&amp;#39; || QUOTE_IDENT(p_search_value) || &amp;#39;&amp;#39;&amp;#39;&amp;#39;&amp;#39;&amp;#39;&amp;#39; || DECODE(LEAD(column_name) OVER(ORDER BY table_schema, table_name, ordinal_position), NULL, &amp;#39;&amp;#39; LIMIT 1);&amp;#39;&amp;#39;, &amp;#39;&amp;#39; LIMIT 1)

        UNION ALL &amp;#39;&amp;#39;) c
            FROM (SELECT table_schema, table_name, column_name, ordinal_position, data_type_id, data_type
            FROM columns WHERE NOT is_system_table AND table_schema ILIKE &amp;#39;&amp;#39;&amp;#39; || QUOTE_IDENT(p_table_schema) || &amp;#39;&amp;#39;&amp;#39; AND data_type_id &amp;lt; 1000
            ORDER BY table_schema, table_name, ordinal_position) foo) foo;&amp;#39;;

    results := EXECUTE &amp;#39;INSERT INTO &amp;#39; || QUOTE_IDENT(p_results_schema) || &amp;#39;.&amp;#39; || QUOTE_IDENT(p_results_table) || &amp;#39; &amp;#39; || sql_cmd_result;

    RAISE INFO &amp;#39;Matches Found: %&amp;#39;, results;
END;
$$;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For example, to search the &lt;code&gt;public&lt;/code&gt; schema for instances of the string &#39;&lt;code&gt;dog&lt;/code&gt;&#39; and then store the results in &lt;code&gt;public.table_list&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; CALL find_my_value(&amp;#39;public&amp;#39;, &amp;#39;dog&amp;#39;, &amp;#39;public&amp;#39;, &amp;#39;table_list&amp;#39;);
 find_my_value
---------------
             0
(1 row)

=&amp;gt; SELECT * FROM public.table_list;
      found_timestamp       | found_value |  table_name   | column_name
----------------------------+-------------+---------------+-------------
 2021-08-25 22:13:20.147889 | dog         | another_table | b
 2021-08-25 22:13:20.147889 | dog         | some_table    | c
(2 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;optimizing-tables&#34;&gt;Optimizing tables&lt;/h2&gt;
&lt;p&gt;You can automate loading data from Parquet files and optimizing your queries with the &lt;code&gt;create_optimized_table()&lt;/code&gt; procedure. This procedure:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Creates an external table whose structure is built from Parquet files using the OpenText™ Analytics Database &lt;a href=&#34;../../../en/sql-reference/functions/management-functions/table-functions/infer-table-ddl/#&#34;&gt;INFER_TABLE_DDL&lt;/a&gt; function.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Creates a native database table, like the external table, resizing all VARCHAR columns to the MAX length of the data to be loaded.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Creates a super projection using the optional segmentation/order by columns passed in as a parameter.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Adds an optional primary key to the native table passed in as a parameter.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Loads a sample data set (1 million rows) from the external table into the native table.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Drops the external table.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Runs the &lt;a href=&#34;../../../en/sql-reference/functions/performance-analysis-functions/statistics-management-functions/analyze-statistics/#&#34;&gt;ANALYZE_STATISTICS&lt;/a&gt; function on the native table.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Runs the &lt;a href=&#34;../../../en/sql-reference/functions/db-designer-functions/designer-design-projection-encodings/#&#34;&gt;DESIGNER_DESIGN_PROJECTION_ENCODINGS&lt;/a&gt; function to get a properly encoded super projection for the native table.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Truncates the now-optimized native table (we will load the entire data set in a separate script/stored procedure).&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;
=&amp;gt; CREATE OR REPLACE PROCEDURE create_optimized_table(p_file_path VARCHAR(1000), p_table_schema VARCHAR(128), p_table_name VARCHAR(128), p_seg_columns VARCHAR(1000), p_pk_columns VARCHAR(1000)) LANGUAGE PLvSQL AS $$
DECLARE
    command_sql VARCHAR(1000);
    seg_columns VARCHAR(1000);
    BEGIN

-- First 3 parms are required.
-- Segmented and PK columns names, if present, must be Unquoted Identifiers
    IF p_file_path IS NULL OR p_file_path = &amp;#39;&amp;#39; THEN
        RAISE EXCEPTION &amp;#39;Please provide a file path.&amp;#39;;
    ELSEIF p_table_schema IS NULL OR p_table_schema = &amp;#39;&amp;#39; THEN
        RAISE EXCEPTION &amp;#39;Please provide a table schema.&amp;#39;;
    ELSEIF p_table_name IS NULL OR p_table_name = &amp;#39;&amp;#39; THEN
        RAISE EXCEPTION &amp;#39;Please provide a table name.&amp;#39;;
    END IF;

-- Pass optional segmented columns parameter as null or empty string if not used
    IF p_seg_columns IS NULL OR p_seg_columns = &amp;#39;&amp;#39; THEN
        seg_columns := &amp;#39;&amp;#39;;
    ELSE
        seg_columns := &amp;#39;ORDER BY &amp;#39; || p_seg_columns || &amp;#39; SEGMENTED BY HASH(&amp;#39; || p_seg_columns || &amp;#39;) ALL NODES&amp;#39;;
    END IF;

-- Add &amp;#39;_external&amp;#39; to end of p_table_name for the external table and drop it if it already exists
    EXECUTE &amp;#39;DROP TABLE IF EXISTS &amp;#39; || QUOTE_IDENT(p_table_schema) || &amp;#39;.&amp;#39; || QUOTE_IDENT(p_table_name) || &amp;#39;_external CASCADE;&amp;#39;;

-- Execute INFER_TABLE_DDL to generate CREATE EXTERNAL TABLE from the Parquet files
    command_sql := EXECUTE &amp;#39;SELECT infer_table_ddl(&amp;#39; || QUOTE_LITERAL(p_file_path) || &amp;#39; USING PARAMETERS format = &amp;#39;&amp;#39;parquet&amp;#39;&amp;#39;, table_schema = &amp;#39;&amp;#39;&amp;#39; || QUOTE_IDENT(p_table_schema) || &amp;#39;&amp;#39;&amp;#39;, table_name = &amp;#39;&amp;#39;&amp;#39; || QUOTE_IDENT(p_table_name) || &amp;#39;_external&amp;#39;&amp;#39;, table_type = &amp;#39;&amp;#39;external&amp;#39;&amp;#39;);&amp;#39;;

-- Run the CREATE EXTERNAL TABLE DDL
    EXECUTE command_sql;

-- Generate the Internal/ROS Table DDL and generate column lengths based on maximum column lengths found in external table
    command_sql := EXECUTE &amp;#39;SELECT LISTAGG(y USING PARAMETERS separator=&amp;#39;&amp;#39; &amp;#39;&amp;#39;)
        FROM ((SELECT 0 x, &amp;#39;&amp;#39;SELECT &amp;#39;&amp;#39;&amp;#39;&amp;#39;CREATE TABLE &amp;#39; || QUOTE_IDENT(p_table_schema) || &amp;#39;.&amp;#39; || QUOTE_IDENT(p_table_name) || &amp;#39;(&amp;#39;&amp;#39; y
            UNION ALL SELECT ordinal_position, column_name || &amp;#39;&amp;#39; &amp;#39;&amp;#39; ||
            CASE WHEN data_type LIKE &amp;#39;&amp;#39;varchar%&amp;#39;&amp;#39;
                THEN &amp;#39;&amp;#39;varchar(&amp;#39;&amp;#39;&amp;#39;&amp;#39; || (SELECT MAX(LENGTH(&amp;#39;&amp;#39; || column_name || &amp;#39;&amp;#39;))
                    FROM &amp;#39;&amp;#39; || table_schema || &amp;#39;&amp;#39;.&amp;#39;&amp;#39; || table_name || &amp;#39;&amp;#39;) || &amp;#39;&amp;#39;&amp;#39;&amp;#39;)&amp;#39;&amp;#39; ELSE data_type END || NVL2(LEAD(&amp;#39;&amp;#39; || column_name || &amp;#39;&amp;#39;, 1) OVER (ORDER BY ordinal_position), &amp;#39;&amp;#39;,&amp;#39;&amp;#39;, &amp;#39;&amp;#39;)&amp;#39;&amp;#39;)
                    FROM columns WHERE table_schema = &amp;#39;&amp;#39;&amp;#39; || QUOTE_IDENT(p_table_schema) || &amp;#39;&amp;#39;&amp;#39; AND table_name = &amp;#39;&amp;#39;&amp;#39; || QUOTE_IDENT(p_table_name) || &amp;#39;_external&amp;#39;&amp;#39;
                    UNION ALL SELECT 10000, &amp;#39;&amp;#39;&amp;#39; || seg_columns || &amp;#39;&amp;#39;&amp;#39; UNION ALL SELECT 10001, &amp;#39;&amp;#39;;&amp;#39;&amp;#39;&amp;#39;&amp;#39;&amp;#39;&amp;#39;) ORDER BY x) foo WHERE y &amp;lt;&amp;gt; &amp;#39;&amp;#39;&amp;#39;&amp;#39;;&amp;#39;;
    command_sql := EXECUTE command_sql;
    EXECUTE command_sql;

-- Alter the Internal/ROS Table if primary key columns were passed as a parameter
    IF p_pk_columns IS NOT NULL AND p_pk_columns &amp;lt;&amp;gt; &amp;#39;&amp;#39; THEN
        EXECUTE &amp;#39;ALTER TABLE &amp;#39; || QUOTE_IDENT(p_table_schema) || &amp;#39;.&amp;#39; || QUOTE_IDENT(p_table_name) || &amp;#39; ADD CONSTRAINT &amp;#39; || QUOTE_IDENT(p_table_name) || &amp;#39;_pk PRIMARY KEY (&amp;#39; || p_pk_columns || &amp;#39;) ENABLED;&amp;#39;;
    END IF;

-- Insert 1M rows into the Internal/ROS Table, analyze stats, and generate encodings
    EXECUTE &amp;#39;INSERT INTO &amp;#39; || QUOTE_IDENT(p_table_schema) || &amp;#39;.&amp;#39; || QUOTE_IDENT(p_table_name) || &amp;#39; SELECT * FROM &amp;#39; || QUOTE_IDENT(p_table_schema) || &amp;#39;.&amp;#39; || QUOTE_IDENT(p_table_name) || &amp;#39;_external LIMIT 1000000;&amp;#39;;

    EXECUTE &amp;#39;SELECT analyze_statistics(&amp;#39;&amp;#39;&amp;#39; || QUOTE_IDENT(p_table_schema) || &amp;#39;.&amp;#39; || QUOTE_IDENT(p_table_name) || &amp;#39;&amp;#39;&amp;#39;);&amp;#39;;

    EXECUTE &amp;#39;SELECT designer_design_projection_encodings(&amp;#39;&amp;#39;&amp;#39; || QUOTE_IDENT(p_table_schema) || &amp;#39;.&amp;#39; || QUOTE_IDENT(p_table_name) || &amp;#39;&amp;#39;&amp;#39;, &amp;#39;&amp;#39;/tmp/toss.sql&amp;#39;&amp;#39;, TRUE, TRUE);&amp;#39;;


-- Truncate the Internal/ROS Table and you are now ready to load all rows
-- Drop the external table

    EXECUTE &amp;#39;TRUNCATE TABLE &amp;#39; || QUOTE_IDENT(p_table_schema) || &amp;#39;.&amp;#39; || QUOTE_IDENT(p_table_name) || &amp;#39;;&amp;#39;;

    EXECUTE &amp;#39;DROP TABLE IF EXISTS &amp;#39; || QUOTE_IDENT(p_table_schema) || &amp;#39;.&amp;#39; || QUOTE_IDENT(p_table_name) || &amp;#39;_external CASCADE;&amp;#39;;

  END;

  $$;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; call create_optimized_table(&amp;#39;/home/dbadmin/parquet_example/*&amp;#39;,&amp;#39;public&amp;#39;,&amp;#39;parquet_table&amp;#39;,&amp;#39;c1,c2&amp;#39;,&amp;#39;c1&amp;#39;);

create_optimized_table
------------------------
                      0
(1 row)

=&amp;gt; select export_objects(&amp;#39;&amp;#39;, &amp;#39;public.parquet_table&amp;#39;);
       export_objects
------------------------------------------
CREATE TABLE public.parquet_table
(
    c1 int NOT NULL,
    c2 varchar(36),
    c3 date,
    CONSTRAINT parquet_table_pk PRIMARY KEY (c1) ENABLED
);


CREATE PROJECTION public.parquet_table_super /*+createtype(D)*/
(
c1 ENCODING COMMONDELTA_COMP,
c2 ENCODING ZSTD_FAST_COMP,
c3 ENCODING COMMONDELTA_COMP
)
AS
SELECT parquet_table.c1,
        parquet_table.c2,
        parquet_table.c3
FROM public.parquet_table
ORDER BY parquet_table.c1,
          parquet_table.c2
SEGMENTED BY hash(parquet_table.c1, parquet_table.c2) ALL NODES OFFSET 0;

SELECT MARK_DESIGN_KSAFE(0);

(1 row)
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;pivoting-tables-dynamically&#34;&gt;Pivoting tables dynamically&lt;/h2&gt;
&lt;p&gt;The stored procedure &lt;code&gt;unpivot()&lt;/code&gt; takes as input a source table and target table. It unpivots the source table and outputs it into a target table.&lt;/p&gt;
&lt;p&gt;This example uses the following table:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT * FROM make_the_columns_into_rows;
c1  | c2  |                  c3                  |             c4             |    c5    | c6
-----+-----+--------------------------------------+----------------------------+----------+----
123 | ABC | cf470c5b-50e3-492a-8483-b9e4f20d195a | 2021-08-24 18:49:40.835802 |  1.72964 | t
567 | EFG | 25ea7636-d924-4b4f-81b5-1e1c884b06e3 | 2021-08-04 18:49:40.835802 | 41.46100 | f
890 | XYZ | f588935a-35a4-4275-9e7f-ebb3986390e3 | 2021-08-29 19:53:39.465778 |  8.58207 | t
(3 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This table contains the following columns:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; \d make_the_columns_into_rows
                                               List of Fields by Tables
Schema |           Table            | Column |     Type      | Size | Default | Not Null | Primary Key | Foreign Key
--------+----------------------------+--------+---------------+------+---------+----------+-------------+-------------
public | make_the_columns_into_rows | c1     | int           |    8 |         | f        | f           |
public | make_the_columns_into_rows | c2     | varchar(80)   |   80 |         | f        | f           |
public | make_the_columns_into_rows | c3     | uuid          |   16 |         | f        | f           |
public | make_the_columns_into_rows | c4     | timestamp     |    8 |         | f        | f           |
public | make_the_columns_into_rows | c5     | numeric(10,5) |    8 |         | f        | f           |
public | make_the_columns_into_rows | c6     | boolean       |    1 |         | f        | f           |
(6 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The target table has columns from the source table pivoted into rows as key/value pairs. It also has a &lt;code&gt;ROWID&lt;/code&gt; column to tie the key/value pairs back to their original row from the source table:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; CREATE PROCEDURE unpivot(p_source_table_schema VARCHAR(128), p_source_table_name VARCHAR(128), p_target_table_schema VARCHAR(128), p_target_table_name VARCHAR(128)) AS $$
DECLARE
    explode_command VARCHAR(10000);
BEGIN
    explode_command := EXECUTE &amp;#39;SELECT &amp;#39;&amp;#39;explode(string_to_array(&amp;#39;&amp;#39;&amp;#39;&amp;#39;[&amp;#39;&amp;#39;&amp;#39;&amp;#39; || &amp;#39;&amp;#39; || LISTAGG(&amp;#39;&amp;#39;NVL(&amp;#39;&amp;#39; || column_name || &amp;#39;&amp;#39;::VARCHAR, &amp;#39;&amp;#39;&amp;#39;&amp;#39;&amp;#39;&amp;#39;&amp;#39;&amp;#39;)&amp;#39;&amp;#39; USING PARAMETERS separator=&amp;#39;&amp;#39; || &amp;#39;&amp;#39;&amp;#39;&amp;#39;,&amp;#39;&amp;#39;&amp;#39;&amp;#39; || &amp;#39;&amp;#39;) || &amp;#39;&amp;#39; || &amp;#39;&amp;#39;&amp;#39;&amp;#39;]&amp;#39;&amp;#39;&amp;#39;&amp;#39;)) OVER (PARTITION BY rn)&amp;#39;&amp;#39; explode_command FROM (SELECT table_schema, table_name, column_name, ordinal_position FROM columns ORDER BY table_schema, table_name, ordinal_position LIMIT 10000000) foo WHERE table_schema = &amp;#39;&amp;#39;&amp;#39; || QUOTE_IDENT(p_source_table_schema) || &amp;#39;&amp;#39;&amp;#39; AND table_name = &amp;#39;&amp;#39;&amp;#39; || QUOTE_IDENT(p_source_table_name) || &amp;#39;&amp;#39;&amp;#39;;&amp;#39;;

    EXECUTE &amp;#39;CREATE TABLE &amp;#39; || QUOTE_IDENT(p_target_table_schema) || &amp;#39;.&amp;#39; || QUOTE_IDENT(p_target_table_name) || &amp;#39;
        AS SELECT rn rowid, column_name key, value FROM (SELECT (ordinal_position - 1) op, column_name
            FROM columns WHERE table_schema = &amp;#39;&amp;#39;&amp;#39; || QUOTE_IDENT(p_source_table_schema) || &amp;#39;&amp;#39;&amp;#39;
            AND table_name = &amp;#39;&amp;#39;&amp;#39; || QUOTE_IDENT(p_source_table_name) || &amp;#39;&amp;#39;&amp;#39;) a
            JOIN (SELECT rn, &amp;#39; || explode_command || &amp;#39;
            FROM (SELECT ROW_NUMBER() OVER() rn, *
            FROM &amp;#39; || QUOTE_IDENT(p_source_table_schema) || &amp;#39;.&amp;#39; || QUOTE_IDENT(p_source_table_name) || &amp;#39;) foo) b ON b.position = a.op&amp;#39;;
END;
$$;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Call the procedure:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; CALL unpivot(&amp;#39;public&amp;#39;, &amp;#39;make_the_columns_into_rows&amp;#39;, &amp;#39;public&amp;#39;, &amp;#39;columns_into_rows&amp;#39;);
 unpivot
---------
       0
(1 row)

=&amp;gt; SELECT * FROM columns_into_rows ORDER BY rowid, key;
rowid | key |                value
-------+-----+--------------------------------------
     1 | c1  | 123
     1 | c2  | ABC
     1 | c3  | cf470c5b-50e3-492a-8483-b9e4f20d195a
     1 | c4  | 2021-08-24 18:49:40.835802
     1 | c5  | 1.72964
     1 | c6  | t
     2 | c1  | 890
     2 | c2  | XYZ
     2 | c3  | f588935a-35a4-4275-9e7f-ebb3986390e3
     2 | c4  | 2021-08-29 19:53:39.465778
     2 | c5  | 8.58207
     2 | c6  | t
     3 | c1  | 567
     3 | c2  | EFG
     3 | c3  | 25ea7636-d924-4b4f-81b5-1e1c884b06e3
     3 | c4  | 2021-08-04 18:49:40.835802
     3 | c5  | 41.46100
     3 | c6  | f
(18 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;unpivot()&lt;/code&gt; procedure can handle new columns in the source table as well.&lt;/p&gt;
&lt;p&gt;Add a new column &lt;code&gt;z&lt;/code&gt; to the source table, and then unpivot the table with the same procedure:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; ALTER TABLE make_the_columns_into_rows ADD COLUMN z VARCHAR;
ALTER TABLE

=&amp;gt; UPDATE make_the_columns_into_rows SET z = &amp;#39;ZZZ&amp;#39; WHERE c1 IN (123, 890);
OUTPUT
--------
      2
(1 row)

=&amp;gt; CALL unpivot(&amp;#39;public&amp;#39;, &amp;#39;make_the_columns_into_rows&amp;#39;, &amp;#39;public&amp;#39;, &amp;#39;columns_into_rows&amp;#39;);
unpivot
---------
       0
(1 row)

=&amp;gt; SELECT * FROM columns_into_rows;
rowid | key |                value
-------+-----+--------------------------------------
     1 | c1  | 567
     1 | c2  | EFG
     1 | c3  | 25ea7636-d924-4b4f-81b5-1e1c884b06e3
     1 | c4  | 2021-08-04 18:49:40.835802
     1 | c5  | 41.46100
     1 | c6  | f
&lt;span class=&#34;code-input&#34;&gt;     1 | z   |&lt;/span&gt;   -- new column
     2 | c1  | 123
     2 | c2  | ABC
     2 | c3  | cf470c5b-50e3-492a-8483-b9e4f20d195a
     2 | c4  | 2021-08-24 18:49:40.835802
     2 | c5  | 1.72964
     2 | c6  | t
&lt;span class=&#34;code-input&#34;&gt;     2 | z   | ZZZ&lt;/span&gt;   -- new column
     3 | c1  | 890
     3 | c2  | XYZ
     3 | c3  | f588935a-35a4-4275-9e7f-ebb3986390e3
     3 | c4  | 2021-08-29 19:53:39.465778
     3 | c5  | 8.58207
     3 | c6  | t
&lt;span class=&#34;code-input&#34;&gt;     3 | z   | ZZZ&lt;/span&gt;   -- new column
(21 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;machine-learning-optimizing-auc-estimation&#34;&gt;Machine learning: optimizing AUC estimation&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&#34;../../../en/sql-reference/functions/ml-functions/model-evaluation/roc/#&#34;&gt;ROC&lt;/a&gt; function can approximate the AUC (area under the curve), the accuracy of which depends on the &lt;code&gt;num_bins&lt;/code&gt; parameter; greater values of &lt;code&gt;num_bins&lt;/code&gt; give you more precise approximations, but may impact performance.&lt;/p&gt;
&lt;p&gt;You can use the stored procedure &lt;code&gt;accurate_auc()&lt;/code&gt; to approximate the AUC, which automatically determines the optimal &lt;code&gt;num_bins&lt;/code&gt; value for a given epsilon (error term):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; CREATE PROCEDURE accurate_auc(relation VARCHAR, observation_col VARCHAR, probability_col VARCHAR, epsilon FLOAT) AS $$
DECLARE
    auc_value FLOAT;
    previous_auc FLOAT;
    nbins INT;
BEGIN
    IF epsilon &amp;gt; 0.25 THEN
        RAISE EXCEPTION &amp;#39;epsilon must not be bigger than 0.25&amp;#39;;
    END IF;
    IF epsilon &amp;lt; 1e-12 THEN
        RAISE EXCEPTION &amp;#39;epsilon must be bigger than 1e-12&amp;#39;;
    END IF;
    auc_value := 0.5;
    previous_auc := 0; -- epsilon and auc should be always less than 1
    nbins := 100;
    WHILE abs(auc_value - previous_auc) &amp;gt; epsilon and nbins &amp;lt; 1000000 LOOP
        RAISE INFO &amp;#39;auc_value: %&amp;#39;, auc_value;
        RAISE INFO &amp;#39;previous_auc: %&amp;#39;, previous_auc;
        RAISE INFO &amp;#39;nbins: %&amp;#39;, nbins;
        previous_auc := auc_value;
        auc_value := EXECUTE &amp;#39;SELECT auc FROM (select roc(&amp;#39; || QUOTE_IDENT(observation_col) || &amp;#39;,&amp;#39; || QUOTE_IDENT(probability_col) || &amp;#39; USING parameters num_bins=$1, auc=true) over() FROM &amp;#39; || QUOTE_IDENT(relation) || &amp;#39;) subq WHERE auc IS NOT NULL&amp;#39; USING nbins;
        nbins := nbins * 2;
    END LOOP;
    RAISE INFO &amp;#39;Result_auc_value: %&amp;#39;, auc_value;
END;
$$;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For example, given the following data in &lt;code&gt;test_data.csv&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;1,0,0.186
1,1,0.993
1,1,0.9
1,1,0.839
1,0,0.367
1,0,0.362
0,1,0.6
1,1,0.726
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;(see &lt;a href=&#34;#test_dat&#34;&gt;test_data.csv&lt;/a&gt; for the complete set of data)&lt;/p&gt;
&lt;p&gt;You can load the data into table &lt;code&gt;categorical_test_data&lt;/code&gt; as follows:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; \set datafile &amp;#39;\&amp;#39;/data/test_data.csv\&amp;#39;&amp;#39;
=&amp;gt; CREATE TABLE categorical_test_data(obs INT, pred INT, prob FLOAT);
CREATE TABLE

=&amp;gt; COPY categorical_test_data FROM :datafile DELIMITER &amp;#39;,&amp;#39;;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Call &lt;code&gt;accurate_auc()&lt;/code&gt;. For this example, the approximated AUC will be within the an epsilon of 0.01:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; CALL accurate_auc(&amp;#39;categorical_test_data&amp;#39;, &amp;#39;obs&amp;#39;, &amp;#39;prob&amp;#39;, 0.01);
INFO 2005:  auc_value: 0.5
INFO 2005:  previous_auc: 0
INFO 2005:  nbins: 100
INFO 2005:  auc_value: 0.749597423510467
INFO 2005:  previous_auc: 0.5
INFO 2005:  nbins: 200
INFO 2005:  Result_auc_value: 0.750402576489533
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a name=&#34;test_dat&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;test_datacsv&#34;&gt;test_data.csv&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;1,0,0.186
1,1,0.993
1,1,0.9
1,1,0.839
1,0,0.367
1,0,0.362
0,1,0.6
1,1,0.726
0,0,0.087
0,0,0.004
0,1,0.562
1,0,0.477
0,0,0.258
1,0,0.143
0,0,0.403
1,1,0.978
1,1,0.58
1,1,0.51
0,0,0.424
0,1,0.546
0,1,0.639
0,1,0.676
0,1,0.639
1,1,0.757
1,1,0.883
1,0,0.301
1,1,0.846
1,0,0.129
1,1,0.76
1,0,0.351
1,1,0.803
1,1,0.527
1,1,0.836
1,0,0.417
1,1,0.656
1,1,0.977
1,1,0.815
1,1,0.869
0,0,0.474
0,0,0.346
1,0,0.188
0,1,0.805
1,1,0.872
1,0,0.466
1,1,0.72
0,0,0.163
0,0,0.085
0,0,0.124
1,1,0.876
0,0,0.451
0,0,0.185
1,1,0.937
1,1,0.615
0,0,0.312
1,1,0.924
1,1,0.638
1,1,0.891
0,1,0.621
1,0,0.421
0,0,0.254
0,0,0.225
1,1,0.577
0,1,0.579
0,1,0.628
0,1,0.855
1,1,0.955
0,0,0.331
1,0,0.298
0,0,0.047
0,0,0.173
1,1,0.96
0,0,0.481
0,0,0.39
0,0,0.088
1,0,0.417
0,0,0.12
1,1,0.871
0,1,0.522
0,0,0.312
1,1,0.695
0,0,0.155
0,0,0.352
1,1,0.561
0,0,0.076
0,1,0.923
1,0,0.169
0,0,0.032
1,1,0.63
0,0,0.126
0,0,0.15
1,0,0.348
0,0,0.188
0,1,0.755
1,1,0.813
0,0,0.418
1,0,0.161
1,0,0.316
0,1,0.558
1,1,0.641
1,0,0.305
&lt;/code&gt;&lt;/pre&gt;
      </description>
    </item>
    
  </channel>
</rss>
