CREATE PROCEDURE statement (external procedures)

Description

Creates an interface to a native or external procedure. To create a SQL procedure, see “CREATE PROCEDURE statement”.

Syntax

CREATEOR REPLACE ] PROCEDUREowner.]procedure-name ( [ parameter, …] ) 
[ RESULTresult-column, …) | NO RESULT SET ]  
[  DYNAMIC RESULT SETS integer-expression ]
 [ SQL SECURITY { INVOKER | DEFINER } ] 
[ EXTERNAL NAME external-call’ [ LANGUAGE environment-name ]

Parameters

parameter:

parameter_mode parameter-name data-typeDEFAULT expression ] | SQLCODE | SQLSTATE

parameter_mode:

IN | OUT | INOUT

result-column:

column-name data-type

environment-name :

C_ESQL32C_ESQL64C_ODBC32C_ODBC64CLRJAVAPERL PHP

Examples

Example 1

This procedure uses a case statement to classify the results of a query.

CREATE PROCEDURE ProductType (IN product_id INT, OUT type CHAR(10))
BEGIN
  DECLARE prod_name CHAR(20) ;
  SELECT name INTO prod_name FROM "GROUPO"."Products"
  WHERE ID = product_id;
  CASE prod_name
  WHEN 'Tee Shirt' THEN
    SET type = 'Shirt'			
  WHEN 'Sweatshirt' THEN
    SET type = 'Shirt'
  WHEN 'Baseball Cap' THEN
    SET type = 'Hat'
  WHEN 'Visor' THEN
    SET type = 'Hat'
  WHEN 'Shorts' THEN
    SET type = 'Shorts'
  ELSE
    SET type = 'UNKNOWN'
  END CASE ;
END

Example 2

This procedure uses a cursor and loops over the rows of the cursor to return a single value.

CREATE PROCEDURE TopCustomer (OUT TopCompany CHAR(35), OUT TopValue INT)
BEGIN
  DECLARE err_notfound EXCEPTION
 	FOR SQLSTATE '02000' ;
  DECLARE curThisCust CURSOR FOR
  SELECT CompanyName, CAST( 	  sum(SalesOrderItems.Quantity *
  Products.UnitPrice) AS INTEGER) VALUE
  FROM Customers
  LEFT OUTER JOIN SalesOrders
  LEFT OUTER JOIN SalesorderItems
  LEFT OUTER JOIN Products
  GROUP BY CompanyName ;


  DECLARE ThisValue INT ;
  DECLARE ThisCompany CHAR(35) ;
  SET TopValue = 0 ;
  OPEN curThisCust ;
  CustomerLoop:
  LOOP
    FETCH NEXT curThisCust
    INTO ThisCompany, ThisValue ;
    IF SQLSTATE = err_notfound THEN
      LEAVE CustomerLoop ;
    END IF ;
    IF ThisValue > TopValue THEN
      SET TopValue = ThisValue ;
      SET TopCompany = ThisCompany ;
      END IF ;
  END LOOP CustomerLoop ;
  CLOSE curThisCust ;
END

Usage

The body of a procedure consists of a compound statement. For information on compound statements, see BEGIN … END statement.

NoteThere are two ways to create stored procedures: ISO/ANSI SQL and T-SQL. BEGIN TRANSACTION, for example, is T-SQL specific when using CREATE PROCEDURE syntax. Do not mix syntax when creating stored procedures. See CREATE PROCEDURE statement [T-SQL].

The CREATE PROCEDURE statement creates a procedure in the database. Users with DBA authority can create procedures for other users by specifying an owner. A procedure is invoked with a CALL statement.

If a stored procedure returns a result set, it cannot also set output parameters or return a return value.

When referencing a temporary table from multiple procedures, a potential issue can arise if the temporary table definitions are inconsistent and statements referencing the table are cached.

See Referencing temporary tables within procedures in SQL Anywhere Server – SQL Usage.

CREATE PROCEDURE You can create permanent stored procedures that call external or native procedures written in a variety of programming languages. You can use PROC as a synonym for PROCEDURE.

Parameter names must conform to the rules for other database identifiers such as column names. They must be a valid SQL data type. See Chapter 3, “SQL Data Types” in Reference: Building Blocks, Tables, and Procedures.

Parameters can be prefixed with one of the keywords IN, OUT, or INOUT. If you do not specify one of these values, parameters are INOUT by default. The keywords have these meanings:

When procedures are executed using CALL, not all parameters need to be specified. If a default value is provided in the CREATE PROCEDURE statement, missing parameters are assigned the default values. If an argument is not provided in the CALL statement, and no default is set, an error is given.

SQLSTATE and SQLCODE are special OUT parameters that output the SQLSTATE or SQLCODE value when the procedure ends. Whether or not a SQLSTATE and SQLCODE parameter is specified, the SQLSTATE and SQLCODE special values can always be checked immediately after a procedure call to test the return status of the procedure.

The SQLSTATE and SQLCODE special values are modified by the next SQL statement. Providing SQLSTATE or SQLCODE as procedure arguments allows the return code to be stored in a variable.

Specifying OR REPLACE (CREATE OR REPLACE PROCEDURE) creates a new procedure, or replaces an existing procedure with the same name. This clause changes the definition of the procedure, but preserves existing permissions. An error is returned if you attempt to replace a procedure that is already in use.

You cannot create TEMPORARY external call procedures.

For more information on returning result sets from procedures, see Chapter 1, “Using Procedures and Batches” in the System Administration Guide: Volume 2.

RESULT The RESULT clause declares the number and type of columns in the result set. The parenthesized list following the RESULT keyword defines the result column names and types. This information is returned by the Embedded SQL DESCRIBE or by ODBC SQLDescribeCol when a CALL statement is being described. Allowed data types are listed in Chapter 3, “SQL Data Types” in Reference: Building Blocks, Tables, and Procedures.

Procedures that call into Embedded SQL (LANGUAGE C_ESQL32, LANGUAGE C_ESQL64) or ODBC (LANGUAGE C_ODBC32, LANGUAGE C_ODBC64) external functions can return 0 or 1 result sets.

Procedures that call into Perl or PHP (LANGUAGE PERL, LANGUAGE PHP) external functions cannot return result sets. Procedures that call native functions loaded by the database server cannot return result sets.

Procedures that call into CLR or Java (LANGUAGE CLR, LANGUAGE JAVA) external functions can return 0, 1, or more result sets.

For more information on returning result sets from procedures, see Chapter 1, “Using Procedures and Batches” in the System Administration Guide: Volume 2.

Some procedures can return more than one result set, with different numbers of columns, depending on how they are executed. For example, this procedure returns two columns under some circumstances, and one in others.

CREATE PROCEDURE names( IN formal char(1))
BEGIN
  IF formal = 'n' THEN
    SELECT GivenName 
    FROM Employees
  ELSE
    SELECT Surname,GivenName 
    FROM Employees
  END IF
END

Procedures with variable result sets must be written without a RESULT clause, or in Transact-SQL. Their use is subject to these limitations:

If your procedure returns only one result set, use a RESULT clause. The presence of this clause prevents ODBC and Open Client applications from describing the result set again after a cursor is open.

To handle multiple result sets, ODBC must describe the currently executing cursor, not the procedure’s defined result set. Therefore, ODBC does not always describe column names as defined in the RESULT clause of the procedure definition. To avoid this problem, use column aliases in the SELECT statement that generates the result set.

See ”Returning result sets from procedures” in SQL Anywhere Server – SQL Usage

NO RESULT SET This clause declares that this procedure returns no result set. This is useful when an external environment needs to know that a procedure does not return a result set.

DYNAMIC RESULT SETS Use this clause with LANGUAGE CLR and LANGUAGE JAVA calls. If the DYNAMIC RESULT SETS clause is not provided, it is assumed that the method returns no result set.

Note that procedures that call into Perl or PHP (LANGUAGE PERL, LANGUAGE PHP) external functions cannot return result sets. Procedures that call native functions loaded by the database server cannot return result sets.

SQL SECURITY The SQL SECURITY clause defines whether the procedure is executed as the INVOKER (the user who is calling the procedure), or as the DEFINER (the user who owns the procedure). The default is DEFINER. For external calls, this clause establishes the ownership context for unqualified object references in the external environment.

When SQL SECURITY INVOKER is specified, more memory is used because annotation must be done for each user that calls the procedure. Also, when SQL SECURITY INVOKER is specified, name resolution is done as the invoker as well. Therefore, care should be taken to qualify all object names (tables, procedures, and so on) with their appropriate owner. For example, suppose user1 creates this procedure:

CREATE PROCEDURE user1.myProcedure()
	RESULT( columnA INT )
	SQL SECURITY INVOKER
	BEGIN
		SELECT columnA FROM table1;
	END;

If user2 attempts to run this procedure and a table user2.table1 does not exist, a table lookup error results. Additionally, if a user2.table1 does exist, that table is used instead of the intended user1.table1. To prevent this situation, qualify the table reference in the statement (user1.table1, instead of just table1).

EXTERNAL NAME LANGUAGE ‘native-call’ native-call:[operating-system: ]function-name@library; ...

A procedure that uses EXTERNAL NAME with a LANGUAGE JAVA clause is a wrapper around a Java method.

operating-system: UNIX A procedure using the EXTERNAL NAME clause with no LANGUAGE attribute defines an interface to a native function written in a programming language such as C. The native function is loaded by the database server into its address space.

The library name can include the file extension, which is typically .dll on Windows and .so on UNIX. In the absence of the extension, the software appends the platform-specific default file extension for libraries. This is a formal example.

CREATE PROCEDURE mystring( IN instr LONG VARCHAR ) 
EXTERNAL NAME
'mystring@mylib.dll;Unix:mystring@mylib.so';

A simpler way to write the preceding EXTERNAL NAME clause, using platform-specific defaults, is as follows:

CREATE PROCEDURE mystring( IN instr LONG VARCHAR )
EXTERNAL NAME 'mystring@mylib';

When called, the library containing the function is loaded into the address space of the database server. The native function will execute as part of the server. In this case, if the function causes a fault, then the database server will be terminated. Because of this, loading and executing functions in an external environment using the LANGUAGE attribute is recommended. If a function causes a fault in an external environment, the database server will continue to run.

For information about native library calls, see ”Calling external libraries from procedures” in SQL Anywhere Server – Programming.

EXTERNAL NAME LANGUAGE ‘c-call’ LANGUAGE { C_ESQL32 | C_ESQL64 | C_ODBC32 | C_ODBC64 } c-call:[operating-system: ]function-name@library; ...

operating-system: UNIX

To call a compiled native C function in an external environment instead of within the database server, the stored procedure or function is defined with the EXTERNAL NAME clause followed by the LANGUAGE attribute specifying one of C_ESQL32, C_ESQL64, C_ODBC32, or C_ODBC64.

When the LANGUAGE attribute is specified, then the library containing the function is loaded by an external process and the external function will execute as part of that external process. In this case, if the function causes a fault, then the database server will continue to run.

This is a sample procedure definition.

CREATE PROCEDURE ODBCinsert( 
IN ProductName CHAR(30),
IN ProductDescription CHAR(50)
)
NO RESULT SET
EXTERNAL NAME 'ODBCexternalInsert@extodbc.dll'
LANGUAGE C_ODBC32;

See ”The ESQL and ODBC external environments” in SQL Anywhere Server – Programming.

EXTERNAL NAME ‘clr-call’ LANGUAGE CLR clr-call : dll-name::function-name  ( param-type-1, ... )

operating-system: UNIX

To call a .NET function in an external environment, the procedure interface is defined with an EXTERNAL NAME clause followed by the LANGUAGE CLR attribute.

A CLR stored procedure or function behaves the same as a SQL stored procedure or function with the exception that the code for the procedure or function is written in a .NET language such as C# or Visual Basic, and the execution of the procedure or function takes place outside the database server (that is, within a separate .NET executable).

This is a sample procedure definition.

CREATE PROCEDURE clr_interface( 
IN p1 INT, 
IN p2 UNSIGNED SMALLINT, 
OUT p3 LONG VARCHAR)
NO RESULT SET
EXTERNAL NAME 'CLRlib.dll::CLRproc.Run( int, ushort, out string )' 
LANGUAGE CLR;

See ”The CLR external environment” in SQL Anywhere Server – Programming.

EXTERNAL NAME ‘perl-call’ LANGUAGE CLR perl-call:  < file=perl-call > $sa_perl_return=perl-sub ($sa_perl_arg0, ... )

To call a Perl function in an external environment, the procedure interface is defined with an EXTERNAL NAME clause followed by the LANGUAGE PERL attribute.

A Perl stored procedure or function behaves the same as a SQL stored procedure or function with the exception that the code for the procedure or function is written in Perl and the execution of the procedure or function takes place outside the database server (that is, within a Perl executable instance).

This is a sample procedure definition.

CREATE PROCEDURE PerlWriteToConsole( IN str LONG VARCHAR) 
NO RESULT SET
EXTERNAL NAME '<file=PerlConsoleExample> 
WriteToServerConsole( $sa_perl_arg0 )' 
LANGUAGE PERL;

See ”The PERL external environment” in SQL Anywhere Server – Programming.

EXTERNAL NAME ‘perl-call’ LANGUAGE PHP  <file=php-fileprint php-func($argv[1], ... )

To call a PHP function in an external environment, the procedure interface is defined with an EXTERNAL NAME clause followed by the LANGUAGE PHP attribute.

A PHP stored procedure or function behaves the same as a SQL stored procedure or function with the exception that the code for the procedure or function is written in PHP and the execution of the procedure or function takes place outside the database server (that is, within a PHP executable instance).

This is a sample procedure definition.

CREATE PROCEDURE PHPPopulateTable() 
NO RESULT SET
EXTERNAL NAME '<file=ServerSidePHPExample>
ServerSidePHPSub()'
LANGUAGE PHP;

See ”The PHP external environment” in SQL Anywhere Server – Programming.

EXTERNAL NAME java-call LANGUAGE JAVAjava-call‘ [   package-name. ] class-name.method-namemethod-signature

method-signature: ([field-descriptor, ... ] ) return-descriptor

A Java method signature is a compact character representation of the types of the parameters and the type of the return value.

To call a Java method in an external environment, the procedure interface is defined with an EXTERNAL NAME clause followed by the LANGUAGE JAVA attribute.

A Java-interfacing stored procedure or function behaves the same as a SQL stored procedure or function with the exception that the code for the procedure or function is written in Java and the execution of the procedure or function takes place outside the database server (that is, within a Java Virtual Machine).

This is a sample procedure definition.

CREATE PROCEDURE HelloDemo( IN
name LONG VARCHAR ) 
NO RESULT SET
EXTERNAL NAME 'Hello.main([Ljava/lang/String;)V'
LANGUAGE JAVA;

See ”The Java external environment” in SQL Anywhere Server – Programming.

Table 1-6: Java field-descriptor and return-descriptor

Field type

Java data type

B

byte

C

char

D

double

F

float

I

int

J

long

Lclass-name;

an instance of the class-name class. The class name must be fully qualified, and any dot in the name must be replaced by a backslash. For example, java/lang/String

S

short

V

void

Z

boolean

[

use one for each dimension of an array

For example:

double some_method(
  boolean a,
  int b,
  java.math.BigDecimal c,
  byte [][] d,
  java.sql.ResultSet[] d ) {
}

would have this signature:

'(ZILjava/math/BigDecimal;[[B[Ljava/sql/ResultSet;)D'

NoteAs procedures are dropped and created, databases created prior to Sybase IQ 12.6 may eventually reach the maximum proc_id limit of 32767, causing CREATE PROCEDURE to return an “Item already exists” error in Sybase IQ 12.6. For workaround, see “Insufficient procedure identifiers,” in Chapter 14, “Troubleshooting Hints,” in the System Administration Guide: Volume 1.


Side effects

Automatic commit.

Standards

Permissions

Must have RESOURCE authority, unless creating a temporary procedure. For external procedures or to create a procedure for another user, must have DBA authority.

See also

ALTER PROCEDURE statement

BEGIN … END statement

CALL statement

DROP statement

EXECUTE IMMEDIATE statement [ESQL] [SP]

GRANT statement