Generally speaking, a procedure is a routine that can accept arguments and returns more than one value meanwhile a function is a routine that can accept arguments and returns one value. Axional Ax library support calling either database procedures or functions.

Return Method
JSResultSet executeFunction("Function name", Object ...args)
JSResultSet executeFunction("Function name", Function<Integer,String> columnNameMap, Object ...args)
Map<String, Object> executeFunction("Function name", Consumer<FunctionCallConfigurator> columnNameMap)
JSResultSet executeProcedure("Procedure name", Object ...args)
JSResultSet executeProcedure("Procedure name", Function<Integer,String> columnNameMap, Object ...args)

1 Execute function

A function in server- side script is defined with the method Ax.db.executeFunction(...). A difference between XSQL and server- side script be in the return value. While in XSQL the return value type is expressly indicated, in server- side script the sfunction returns a JSResultSet class. You need to add a method to return the expected type.

1.1 Single value

The simpliest data that can be returned in a function is a basic type value.

Copy
<xsql-script>
    <body>
    	<set name='m_alm_code'>TRI08</set>
    	<set name='m_art_code'>S00167</set>
    	
    	<nativesql>
    	    -- ======================================================                                                                           
            --  test_average_cost: Returns the fixed value '15.25'   
            -- ======================================================
            DROP FUNCTION IF EXISTS test_average_cost;
            CREATE FUNCTION test_average_cost(
                p_alm_code CHAR(10),
                p_art_code CHAR(10)
            )
            
                    RETURNING decimal(14,2);
            
                DEFINE m_alm_code CHAR(10);
                DEFINE m_art_code CHAR(10);
                DEFINE m_avg_cost DECIMAL(14,2);
            
                LET m_avg_cost = 15.25;
            
                RETURN m_avg_cost;
            END FUNCTION;
    	</nativesql>
    	
    	<!-- ================================================================ -->
    	<!--                                                                  -->
        <!-- In this section of the code call the function and set the        -->
        <!-- value into a variable.                                           -->
        <!--                                                                  -->
        <!-- ================================================================ -->
        <set name='m_avg_cost' type='decimal'>
            <execute-function name='test_average_cost' return-type='decimal'>
                <m_alm_code />                       
                <m_art_code/>                                             
            </execute-function>
        </set>
        
        <println>Average amount: [<m_avg_cost />]</println> 
        
        <nativesql>
            DROP FUNCTION IF EXISTS test_average_cost;
        </nativesql>
    </body>
</xsql-script>
Average amount: [15.25]
Copy
var mStrAlmCode  = 'TRI08';
var mStrArtCode  = 'S00167';

    Ax.db.execute(`
        -- ======================================================                                                                           
        --  test_average_cost: Returns the fixed value '15.25'   
        -- ======================================================
        DROP FUNCTION IF EXISTS test_average_cost;
        CREATE FUNCTION test_average_cost(
            p_alm_code CHAR(10),
            p_art_code CHAR(10)
        )
        
            RETURNING decimal(14,2);
        
            DEFINE m_alm_code CHAR(10);
            DEFINE m_art_code CHAR(10);
            DEFINE m_avg_cost DECIMAL(14,2);
        
            LET m_avg_cost = 15.25;
        
            RETURN m_avg_cost;
        END FUNCTION;
    `);

/**
 * In this section of the code call the function. 
 * The expected return type is numeric. 
 * In this case, you need to add toValue() method
 */
var mStrAvgCost = Ax.db.executeFunction('test_average_cost',
            mStrAlmCode, mStrArtCode).toValue();
     
console.log(`Average amount: [${mStrAvgCost}]`);

Ax.db.execute(`DROP FUNCTION IF EXISTS test_average_cost;`);
Average amount: [15.25]

It is also possible to call the function without having to declare the parameters one by one, by grouping them in an array.

Copy
<xsql-script>
    <body>
    	<set name='m_num1'>12</set>
    	<set name='m_num2'>10.5</set>
    	
    	<nativesql>
    	    -- ========================================================                                                                           
            --  test_multiplies: 
            --  Receives two parameters and returns the value of a
            --  multiplication   
            -- ========================================================
            DROP FUNCTION IF EXISTS test_multiplies;
            CREATE FUNCTION test_multiplies(
                p_num1 DECIMAL(14,2),
                p_num2 DECIMAL(14,2)
            )
            
                RETURNING DECIMAL (14,2);
    
                DEFINE m_result DECIMAL(14,2);
            
                LET m_result = p_num1 * p_num2;
            
                RETURN m_result;
            END FUNCTION;
    	</nativesql>
    	
    	<!-- ================================================================ -->
    	<!--                                                                  -->
        <!-- In this section of the code call the function and set the        -->
        <!-- value into a variable.                                           -->
        <!--                                                                  -->
        <!-- ================================================================ -->
        <set name='m_result' type='decimal'>
            <execute-function name='test_multiplies' return-type='decimal'>
                <m_num1 />                       
                <m_num2/>                                             
            </execute-function>
        </set>
        
        <println>Multiplication: [<m_result />]</println>   
        
        <nativesql>
            DROP FUNCTION IF EXISTS test_multiplies;
        </nativesql>
    </body>
</xsql-script>
Multiplication: [126.00]
Copy
var mIntNum1 = 12;
var mIntMul2 = 10.5;
var mArrTest = [mIntNum1, mIntMul2];

    Ax.db.execute(`
        -- ========================================================                                                                           
        --  test_multiplies: 
        --  Receives two parameters and returns the value of a
        --  multiplication   
        -- ========================================================
        DROP FUNCTION IF EXISTS test_multiplies;
        CREATE FUNCTION test_multiplies(
            p_num1 DECIMAL(14,2),
            p_num2 DECIMAL(14,2)
        )
        
            RETURNING DECIMAL (14,2);

            DEFINE m_result DECIMAL(14,2);
        
            LET m_result = p_num1 * p_num2;
        
            RETURN m_result;
        END FUNCTION;
    `);

/**
 * In this section of the code, call the function. 
 * Instead of declaring the parameters one by one, use an array.
 * In this case, you also need to add toValue() method
 */
var mBcResult = Ax.db.executeFunction('test_multiplies',
            mArrTest).toValue();
     
console.log(`Multiplication: [${mBcResult}]`);

Ax.db.execute(`DROP FUNCTION IF EXISTS test_multiplies;`);
Multiplication: [126.00]

2 Execute procedure

To execute a stored procedure, the most common approach is for an application or user to call the procedure.

Copy
<xsql-script>
    <body>
        <set name='m_alm_code'>TRI08</set>
        <set name='m_delega'>08</set>
        <set name='m_depart'>81</set>
        
        <nativesql>
            -- ===================================================
            -- test_get_terenv: Obtener tercero de envío '90001'
            -- ===================================================
            DROP PROCEDURE IF EXISTS test_get_terenv;
            CREATE PROCEDURE test_get_terenv(
                m_alm_code CHAR(10),
                m_delega   CHAR(6),
                m_depart   CHAR(6)
            )
            
                RETURNING CHAR(12) AS o_terenv,
                		  CHAR(6)  AS o_direnv;
            
                DEFINE o_terenv CHAR(12);
                DEFINE o_direnv CHAR(6);
            
                LET o_terenv = '90001';
                LET o_direnv = '01';
            
                RETURN o_terenv,
                	   o_direnv;	
            
            END PROCEDURE;
        </nativesql>

        <execute-procedure name='test_get_terenv'>
            <in>
                <m_alm_code/>
                <m_delega />
                <m_depart />
            </in>
            <out>
                <var name='o_terenv' type='string' />
                <var name='o_direnv' type='string' />
            </out>
        </execute-procedure>
        
        <println>Third delivery: [<o_terenv />] and shipping address: [<o_direnv />]</println> 
        
        <nativesql>
            DROP PROCEDURE IF EXISTS test_get_terenv;
        </nativesql>
    </body>
</xsql-script>
Third delivery: [90001] and shipping address: [01]
Copy
let mStrAlmCode = 'TRI08';
let mStrDelega = '08';
let mStrDepart = '81';

    Ax.db.execute(`
        -- ===================================================
        -- test_get_terenv: Obtener tercero de envío '90001'
        -- ===================================================
        DROP PROCEDURE IF EXISTS test_get_terenv;
        CREATE PROCEDURE test_get_terenv(
            m_alm_code CHAR(10),
            m_delega   CHAR(6),
            m_depart   CHAR(6)
        )
        
            RETURNING CHAR(12) AS o_terenv,
            		  CHAR(6)  AS o_direnv;
        
            DEFINE o_terenv CHAR(12);
            DEFINE o_direnv CHAR(6);
        
            LET o_terenv = '90001';
            LET o_direnv = '01';
        
            RETURN o_terenv,
            	   o_direnv;	
        
        END PROCEDURE;
    `);

let mObjResultado = Ax.db.executeProcedure('test_get_terenv',  columnIndex => {
                switch  (columnIndex) {
                    case 1:  return 'o_terenv';
                    case 2:  return 'o_direnv';
                    default: return "undefined";
                }
            },
            mStrAlmCode, 
            mStrDelega, 
            mStrDepart
        ).toOne();
     
console.log(`Third delivery: [${mObjResultado}]`);

Ax.db.execute(`DROP PROCEDURE test_get_terenv;`);
Third delivery: [90001] and shipping address: [01]