Istruzione CREATE PROCEDURE

Le istruzioni CREATE FUNCTION e CREATE PROCEDURE definiscono una procedura o una funzione richiamabile, generalmente detta routine.

SINTASSI

Note:
  1. Se il tipo di routine è FUNCTION, l'indicatore di direzione (IN, OUT, INOUT) è facoltativo per ciascun parametro. Tuttavia, si consiglia di specificare un indicatore di direzione per tutte le nuove routine di qualsiasi tipo.
  2. Quando viene utilizzata la clausola NAMESPACE o NAME, il relativo valore è implicitamente costante e di tipo CHARACTER. Per informazioni relative all'utilizzo delle variabili CONSTANT, consultare Istruzione DECLARE.
  3. Se il tipo di routine è FUNCTION, non è possibile specificare un LANGUAGE del DATABASE.

Panoramica

Le istruzioni CREATE FUNCTION e CREATE PROCEDURE definiscono una procedura o una funzione richiamabile, generalmente detta routine.

Nota: Nelle versioni precedenti del prodotto, CREATE FUNCTION e CREATE PROCEDURE avevano funzioni ed utilizzo differenti. Tuttavia, sono state potenziate fino al punto in cui restano solo alcune differenze. Gli unici modi in cui le funzioni sono diverse dalle procedure sono elencati nelle note 1 e 3 al di sotto del diagramma di sintassi.

Le routine sono utili per la creazione di blocchi di codice riutilizzabili che possono essere eseguiti in modo indipendente più volte. Esse possono essere implementate come una serie di istruzioni ESQL, un metodo Java oppure una procedura memorizzata del database. Tale flessibilità significa che alcune delle clausole nel diagramma di sintassi non sono applicabili (o consentite) per tutti i tipi di routine.

Ciascuna routine ha un nome, che deve essere univoco all'interno dello schema a cui appartiene. Ciò significa che i nomi delle routine non possono essere sovraccaricati; se il broker rileva che una routine è stata sovraccaricata, genera un'eccezione.

La clausola LANGUAGE specifica il linguaggio in cui è scritto il contenuto della routine. Le opzioni sono:
DATABASE
La procedura viene richiamata come una procedura memorizzata del database.
ESQL
La procedura viene richiamata come una routine ESQL.
JAVA
La procedura viene richiamata come un metodo statico in una classe Java.
Non specificata
Se non si specifica la clausola LANGUAGE, il linguaggio predefinito è ESQL a meno che non venga specificata la clausola EXTERNAL NAME; in questo caso, il linguaggio predefinito è DATABASE.
Esistono alcune limitazioni relative all'utilizzo della clausola LANGUAGE. Non utilizzare:
  • L'opzione ESQL con una clausola EXTERNAL NAME
  • Le opzioni DATABASE o JAVA senza una clausola EXTERNAL NAME
  • L'opzione DATABASE con un tipo di routine FUNCTION

Specificare il nome della routine utilizzando la clausola RoutineName ed i parametri della routine utilizzando la clausola ParameterList. Se la clausola LANGUAGE specifica ESQL, la routine deve essere implementata utilizzando un'istruzione ESQL singola. Questa istruzione è più utile se si tratta di un'istruzione composta (BEGIN ... END) perché può contenere tutte le istruzioni ESQL necessarie per il proprio funzionamento.

In alternativa, invece di fornire un contenuto ESQL per la routine, è possibile specificare una clausola LANGUAGE diversa da ESQL. Ciò consente di utilizzare la clausola EXTERNAL NAME per fornire un riferimento al contenuto reale della routine, anche se posizionata esternamente al broker. Per ulteriori dettagli relativi all'utilizzo della clausola EXTERNAL NAME, consultare Richiamo delle procedure memorizzate e Richiamo di una routine Java.

Le routine di qualsiasi tipo LANGUAGE possono avere parametri IN, OUT ed INOUT. Ciò consente al chiamante di passare diversi valori alla routine e di ricevere diversi valori aggiornati. Tali parametri sono in aggiunta alla clausola RETURNS che può avere la routine. La clausola RETURNS consente alla routine di passare un valore al chiamante.

Le routine implementate in linguaggi differenti hanno le proprie limitazioni relative ai tipi di dati che possono essere passati o restituiti, come riportato di seguito. Il tipo di dati del valore restituito deve corrispondere al tipo di dati del valore definito per essere restituito dalla routine. Inoltre, se una routine è definita in modo da avere un valore di ritorno, questa caratteristica non può essere ignorata dal chiamante della routine. Per ulteriori dettagli, consultare Istruzione CALL.

Le routine possono essere definite in un modulo o uno schema. Le routine definite in un modulo sono locali nell'ambito del nodo corrente, per cui possono essere richiamate solo dal codice che appartiene allo stesso modulo (o nodo). Le routine definite nell'ambito dello schema, tuttavia, possono essere richiamate da:
  • Codice nello stesso schema.
  • Codice in qualsiasi altro schema, se sono valide le condizioni riportate di seguito:
    1. La clausola PATH dell'altro schema contiene il percorso della routine chiamata oppure
    2. La routine viene richiamata mediante il relativo nome completo (nome, preceduto dal nome dello schema, separati da un punto).
Per questo motivo, se è necessario richiamare la stessa routine in più di un nodo, definirla in uno schema.

Per qualsiasi tipo di routine o linguaggio, il metodo di richiamo della routine deve corrispondere al modo in cui la routine è stata dichiarata. Se la routine ha una clausola RETURNS, utilizzare la sintassi di richiamo di FUNCTION oppure un'istruzione CALL con una clausola INTO. Al contrario, se una routine non ha la clausola RETURNS, è necessario utilizzare un'istruzione CALL senza la clausola INTO.

Direzioni dei parametri

Ai parametri passati alle routine è sempre associata una direzione. Questa può essere una tra:
IN
Il valore del parametro non può essere modificato dalla routine. Il valore NULL per il parametro è consentito e può essere passato alla routine.
OUT
Quando viene ricevuto dalla routine richiamata, il parametro passato alla routine ha sempre un valore NULL del tipo di dati corretto. Ciò si verifica indipendentemente dal valore prima che venga richiamata la routine. La routine può modificare il valore del parametro.
INOUT
INOUT è un parametro IN e OUT. Esso passa un valore alla routine e tale valore può essere modificato dalla routine. Il valore NULL per il parametro è consentito e può essere passato sia all'interno che all'esterno della routine.

Se il tipo di routine è FUNCTION, l'indicatore di direzione (IN, OUT, INOUT) è facoltativo per ciascun parametro. Tuttavia, si consiglia di specificare un indicatore di direzione per tutte le nuove routine di qualsiasi tipo.

Le variabili ESQL dichiarate come CONSTANT (o i riferimenti alle variabili dichiarati come CONSTANT) non possono avere la direzione OUT o INOUT.

Routine ESQL

Le routine ESQL sono scritte in ESQL ed hanno la clausola LANGUAGE uguale a ESQL. Il contenuto di una routine ESQL è generalmente un'istruzione composta del formato BEGIN … END, che contiene più istruzioni per l'elaborazione dei parametri passati alla routine.

Esempio ESQL 1

L'esempio riportato di seguito mostra la stessa procedura riportata in Esempio di routine del database 1, ma implementata come routine ESQL invece che come procedura memorizzata. La sintassi di CALL ed i risultati di questa routine sono uguali a quelli in Limitazioni per le routine Java.
CREATE PROCEDURE swapParms (
  IN parm1 CHARACTER,
  OUT parm2  CHARACTER,
  INOUT parm3 CHARACTER )
BEGIN
   SET parm2 = parm3;
   SET parm3 = parm1;
 END; 

Esempio ESQL 2

Questa procedura di esempio illustra l'utilizzo ricorsivo di una routine ESQL. La procedura analizza una struttura ad albero, visitando tutte le posizioni al livello ed al di sotto del punto iniziale specificato e riporta le informazioni rilevate:

SET OutputRoot.MQMD = InputRoot.MQMD;

  DECLARE answer CHARACTER;
  SET     answer = '';

  CALL navigate(InputRoot.XML, answer);
  SET OutputRoot.XML.Data.FieldNames = answer;


  CREATE PROCEDURE navigate (IN root REFERENCE, INOUT answer CHARACTER)
  BEGIN
    SET answer = answer || 'Reached Field... Type:' 
    || CAST(FIELDTYPE(root) AS CHAR)||
    ': Name:' || FIELDNAME(root) || ': Value :' || root || ': ';

    DECLARE cursor REFERENCE TO root;
    MOVE cursor FIRSTCHILD;
    IF LASTMOVE(cursor) THEN
      SET answer = answer || 'Field has children... drilling down ';
    ELSE
      SET answer = answer || 'Listing siblings... ';
    END IF;

    WHILE LASTMOVE(cursor) DO
      CALL navigate(cursor, answer);
      MOVE cursor NEXTSIBLING;
    END WHILE;

    SET answer = answer || 'Finished siblings... Popping up ';
  END;

Quando viene fornito il seguente messaggio di input:

<Person>
  <Name>John Smith</Name>
  <Salary period='monthly' taxable='yes'>-1200</Salary>
</Person>

la procedura genera il seguente output, formattato manualmente:

  Reached Field... Type:16777232: Name:XML: Value :: Field has children... 
  drilling down 
  Reached Field... Type:16777216: Name:Person: Value :: Field has children...
  drilling down 
  Reached Field... Type:16777216: Name:Name: 
  Value :John Smith: Field has children... drilling down 
  Reached Field... Type:33554432: Name:: 
  Value :John Smith: Listing siblings... Finished siblings... Popping up
  Finished siblings... Popping up 
  Reached Field... Type:16777216: Name:Salary:
  Value :-1200: Field has children... drilling down 
  Reached Field... Type:50331648: Name:period: 
  Value :monthly: Listing siblings... Finished siblings... Popping up
  Reached Field... Type:50331648: Name:taxable: 
  Value :yes: Listing siblings... Finished siblings... Popping up 
  Reached Field... Type:33554432: Name:: 
  Value :-1200: Listing siblings... Finished siblings... Popping up 
  Finished siblings... Popping up 
  Finished siblings... Popping up 
  Finished siblings... Popping up

Routine Java

Una routine Java è implementata come un metodo Java ed ha la clausola LANGUAGE impostata su JAVA. Per le routine Java, ExternalRoutineName deve contenere il nome della classe ed il nome del metodo Java da richiamare. Specificare ExternalRoutineName come riportato di seguito:
 >>--"-- className---.---methodName--"--------------><
dove className identifica la classe che contiene il metodo e methodName identifica il metodo da richiamare. Se la classe fa parte di un pacchetto, la parte relativa all'identificativo della classe deve includere il prefisso del pacchetto completo; ad esempio, "com.ibm.broker.test.MyClass.myMethod".

Per individuare la classe Java, il broker esegue una ricerca nel modo descritto in Distribuzione di classi Java.

Qualsiasi metodo Java che si desidera richiamare deve avere la seguente firma di base:
public static <return-type> <method-name> (< 0 - N parameters>)

dove <return-type> deve essere nell'elenco dei tipi di dati IN di Java nella tabella in Mappatura da ESQL a tipo di dati Java (escluso il tipo REFERENCE, che non è consentito come valore di ritorno) oppure il tipo di dati void di Java. Anche i tipi di dati del parametro devono essere contenuti nella tabella Mappatura da ESQL a tipo di dati Java. Inoltre, il metodo Java non può contenere una clausola exception throws nella propria firma.

La firma del metodo di Java deve corrispondere alla dichiarazione del metodo della routine ESQL. Inoltre, è necessario rispettare le regole riportate di seguito:
  • Verificare che il nome del metodo Java, incluso il nome della classe ed i qualificatori del pacchetto, corrisponda a EXTERNAL NAME della procedura.
  • Se il tipo di ritorno Java è void, non inserire una clausola RETURNS nella definizione della routine ESQL. Al contrario, se il tipo di ritorno Java è not void, si deve inserire una clausola RETURNS nella definizione della routine ESQL.
  • Verificare che tutti i tipi di parametro e le direzioni corrispondano alla dichiarazione ESQL, in base alle regole elencate nella tabella in Mappatura da ESQL a tipo di dati Java.
  • Verificare che il tipo di ritorno del metodo corrisponda al tipo di dati della clausola RETURNS.
  • Racchiudere EXTERNAL NAME tra apici, poiché deve contenere almeno “class.method”.
  • Se si desidera richiamare un metodo Java sovraccaricato, è necessario creare una definizione ESQL separata per ciascun metodo sovraccaricato e fornire a ciascuna definizione ESQL un nome di routine univoco.

E0 possibile utilizzare l'API UDN (User defined Node) Java nel proprio metodo Java se si osservano le limitazioni riportate in Limitazioni per le routine Java. Per ulteriori informazioni relative all'utilizzo dell'API UDN, consultare Compilazione di un nodo definito dall'utente in Java.

Esempio di routine Java 1

Questa routine contiene tre parametri di direzione variabile e restituisce un integer che corrisponde ad un tipo di ritorno Java uguale a java.lang.Long.

CREATE FUNCTION  myProc1( IN P1 INTEGER, OUT P2 INTEGER, INOUT P3 INTEGER )
 RETURNS INTEGER
 LANGUAGE JAVA 
 EXTERNAL NAME "com.ibm.broker.test.MyClass.myMethod1";

E' possibile utilizzare il seguente codice ESQL per richiamare myProc1:

CALL myProc1( intVar1, intVar2, intVar3) INTO intReturnVar3;
-- or
SET intReturnVar3 = myProc1( intVar1, intVar2, intVar3);

Esempio di routine Java 2

Questa routine contiene tre parametri di direzione variabile ed ha un tipo di ritorno Java uguale a void.

CREATE PROCEDURE myProc2( IN P1 INTEGER, OUT P2 INTEGER, INOUT P3 INTEGER )
 LANGUAGE JAVA 
 EXTERNAL NAME "com.ibm.broker.test.MyClass.myMethod2";

E' necessario utilizzare il seguente codice ESQL per richiamare myProc2:

CALL myProc2(intVar1, intVar2, intVar3);

La seguente classe Java fornisce un metodo per ciascuno degli esempi Java precedenti:

package com.ibm.broker.test;

class MyClass {
public static Long myMethod1( Long P1, Long[] P2 Long[] P3) { ... }
public static void myMethod2( Long P2, Long[] P2 Long[] P3) { ... }

 /* When either of these methods is called:
    P1 may or may not be NULL (depending on the value of intVar1).
    P2[0] is always NULL (whatever the value of intVar2).
    P3[0] may or may not be NULL (depending on the value of intVar3).  
    This is the same as with LANGUAGE ESQL routines. 
    When these methods return:
         intVar1 is unchanged
         intVar2 may still be NULL or may have been changed
         intVar3 may contain the same value or may have been changed.
     This is the same as with LANGUAGE ESQL routines.
     
    When myMethod1 returns: intReturnVar3 is either  NULL (if the
    method returns NULL) or it contains the value returned by the 
    method.
 */
}

Mappatura da ESQL a tipo di dati Java

La tabella riportata di seguito riepilogo le associazioni da ESQL a Java.
Note:
  • Solo i wrapper scalari Java vengono passati a Java.
  • I tipi scalari ESQL vengono associati ai tipi di dati Java come wrapper di oggetti o array di wrapper di oggetti, in base alla direzione del parametro della procedura. Ciascun array di wrapper contiene esattamente un elemento.
  • I wrapper degli oggetti scalari vengono utilizzati per consentire ai valori NULL di passare ai e dai metodi Java.
Tipi di dati ESQL 1 Tipi di dati IN Java Tipi di dati INOUT Java
INTEGER, INT java.lang.Long java.lang.Long []
FLOAT java.lang.Double java.lang.Double[]
DECIMAL java.math.BigDecimal java.math.BigDecimal[]
CHARACTER, CHAR java.lang.String java.lang.String[]
BLOB byte[] byte[][]
BIT java.util.BitSet java.util.BitSet[]
DATE com.ibm.broker.plugin.MbDate com.ibm.broker.plugin.MbDate[]
TIME 2 com.ibm.broker.plugin.MbTime com.ibm.broker.plugin.MbTime[]
GMTTIME 2 com.ibm.broker.plugin.MbTime com.ibm.broker.plugin.MbTime[]
TIMESTAMP 2 com.ibm.broker.plugin.MbTimestamp com.ibm.broker.plugin.MbTimestamp[]
GMTTIMESTAMP 2 com.ibm.broker.plugin.MbTimestamp com.ibm.broker.plugin.MbTimestamp[]
INTERVAL Non supportato Non supportato
BOOLEAN java.lang.Boolean java.lang.Boolean[]
REFERENCE (ad una struttura ad albero del messaggio) 3 4 5 6 com.ibm.broker.plugin.MbElement com.ibm.broker.plugin.MbElement[] (Supportato per INOUT. Non supportato per OUT)
ROW Non supportato Non supportato
LIST Non supportato Non supportato
  1. Le variabili dichiarate come CONSTANT (o i riferimenti alle variabili dichiarate come CONSTANT) non possono avere la direzione INOUT oppure OUT.
  2. Il fuso orario impostato nella variabile Java non è importante; il fuso orario richiesto viene ottenuto nel codice ESQL di output.
  3. Il parametro di riferimento non può essere NULL quando viene passato in un metodo Java.
  4. Il riferimento non può avere la direzione OUT quando viene passato in un metodo Java.
  5. Se un MbElement viene passato da Java a ESQL come parametro INOUT, deve puntare ad una posizione nella stessa struttura ad albero del messaggio come quella indicata da MbElement passato nel metodo Java richiamato.

    Ad esempio, se un riferimento ESQL a OutputRoot.XML.Test viene passato in un metodo Java come MbElement INOUT, ma un altro MbElement diverso viene passato a ESQL quando la chiamata ritorna, l'elemento differente deve puntare in un a posizione nella struttura ad albero OutputRoot.

  6. Un MbElement non può essere restituito da un metodo Java con la clausola RETURNS, perché nessuna routine ESQL può restituire un riferimento. Tuttavia, un MbElement può essere restituito come parametro di direzione INOUT, soggetto alla condizioni descritte nel punto 5 sopra riportato.

Un REFERENCE ad una variabile scalare può essere utilizzato nella CALL di un metodo Java se il tipo di dati della variabile indicata dal riferimento corrisponde al tipo di dati corrispondente nella firma del programma Java.

Limitazioni per le routine Java

Le seguenti limitazioni sono valide per le routine Java richiamate da ESQL:
  • E' necessario assicurarsi che il metodo Java sia threadsafe (reentrant).
  • Le uniche connessioni al database consentite sono le connessioni JDBC tipo 4. Inoltre, le operazioni del database non sono parte di una transazione del broker; ciò significa che non possono essere controllate da un coordinatore di risorse esterno (come nel caso di un ambiente XA).
  • L'API UDN (User defined Node) Java deve essere utilizzata dolo dallo stesso thread che ha richiamato il metodo Java.

    E' possibile moltiplicare i thread all'interno del proprio metodo. Tuttavia, i metodi moltiplicati non devono utilizzare le API plug-in Java ed è necessario restituire il controllo al broker.

    Notare che tutte le limitazioni valide per l'utilizzo dell'API UDN sono valide anche per i metodi Java richiamati da ESQL.

  • I metodi Java richiamati da ESQL non devono utilizzare la classe MbNode. Ciò significa che non possono creare oggetti di tipo MbNode oppure richiamare i metodi su un oggetto MbNode esistente.
  • Se si desidera eseguire un lavoro MQ o JMS all'interno di un metodo Java richiamato da ESQL, è necessario seguire le linee guida UDN (User Defined Node) per l'esecuzione di lavori MQ e JMS in un UDN.

Distribuzione di classi Java

E' possibile distribuire le proprie classi Java all'interno di file JAR (Java Archive). E' possibile distribuire un file JAR al broker in due modi:
  1. Aggiungendolo al file BAR (Broker Archive)

    L'aggiunta del file JAR al file BAR è il metodo più efficace e flessibile di distribuzione del broker.

    E' possibile aggiungere un file JAR al file BAR manualmente oppure automaticamente, utilizzando gli strumenti. L'utilizzo di strumenti è il modo più semplice per aggiungere un file JAR a un file BAR.

    Se gli strumenti individuano la classe Java corretta all'interno di un progetto Java aperto nello spazio di lavoro, la classe Java Viene automaticamente compilata in un file JAR e viene aggiunta al file BAR. Questa è la stessa procedura seguita per distribuire un nodo Java Compute all'interno di un JAR, come descritto in Classloading del nodo definito dall'utente.

    Quando si distribuisce un file JAR dagli strumenti, una nuova distribuzione del file BAR contenente il file JAR implica che le classi Java di riferimento vengano caricate nuovamente dal flusso ridistribuito; lo stesso funzionamento si verifica se si arresta e riavvia un flusso di messaggi che fa riferimento ad una classe Java. Assicurarsi di arrestare e riavviare (o ridistribuire) tutti i flussi che fanno riferimento al file JAR che si desidera aggiornare. In questo modo, si evita il problema di alcuni flussi in esecuzione con la versione obsoleta del file JAR ed altri in esecuzione con la nuova versione.

    Notare che gli strumenti distribuiscono solo un file JAR; non distribuiscono un file di classe Java autonomo.

  2. Posizionandolo all'interno di uno dei seguenti:
    1. La cartella <Workpath>/shared-classes/ sulla macchina su cui il broker è in esecuzione
    2. Variabile di ambiente CLASSPATH della macchina su cui è in esecuzione il broker

    Questa procedura deve essere eseguita manualmente; non è possibile utilizzare gli strumenti.

    In questo metodo, la ridistribuzione del flusso di messaggi non carica nuovamente le classi Java di riferimento, allo stesso modo dell'arresto e del riavvio del flusso di messaggi. L'unico modo per caricare nuovamente le classi, in questo caso, è quello di arrestare e riavviare il broker.

Per consentire al broker di individuare una classe Java, verificare che si trovi in una delle ubicazioni sopra indicate. Se il broker non riesce ad individuare la classe specificata, genera un'eccezione.

Sebbene siano disponibili le scelte sopra indicate quando si distribuisce il file JAR, consentendo agli strumenti di distribuire il file BAR, si fornisce la maggiore flessibilità quando si ridistribuisce il file JAR.

Routine del database

Le routine del database sono routine implementate come procedure memorizzate del database. Le routine del database hanno la clausola LANGUAGE uguale a DATABASE e devono avere il tipo di routine PROCEDURE.

Quando si scrivono procedure memorizzate in linguaggi come C, è necessario utilizzare indicatori NULL per assicurarsi che la procedura possa elaborare i dati correttamente.

Sebbene le definizioni del database di una procedura memorizzata variano tra i database, il codice ESQL utilizzato per richiamarle è uguale. I nomi assegnati ai parametri in ESQL non devono corrispondere ai nomi assegnati sul database. Tuttavia, il nome esterno della routine, incluse le specifiche del contenitore o del pacchetto, deve corrispondere al proprio nome definito nel database.

La clausola DYNAMIC RESULT SET è consentita solo per le routine del database. È obbligatoria solo se una procedura memorizzata restituisce una o più serie di risultati. Il parametro integer per questa clausola deve essere 0 (zero) o un valore maggiore e specifica il numero di serie di risultati da restituire.

La clausola facoltativa RETURNS è necessaria se una procedura memorizzata restituisce un valore scalare singolo.

La clausola EXTERNAL NAME specifica il nome con cui il database riconosce la routine. Questo può essere un nome qualificato o non qualificato, in cui il qualificatore è il nome dello schema del database in cui è definita la procedura. Se non viene fornito un nome dello schema, viene utilizzato il nome utente per la connessione al database come schema in cui individuare la procedura. Se la procedura richiesta non esiste in questo schema, è necessario fornire un nome di schema esplicito nella definizione della routine oppure nella CALL alla routine al runtime. Per ulteriori informazioni relative alla scelta dinamica dello schema che contiene la routine, consultare Istruzione CALL. Quando viene utilizzato un nome qualificato, il nome deve essere racchiuso tra apici.

Generalmente, il formato di una routine completa è il seguente:
 EXTERNAL NAME "mySchema.myProc";
Tuttavia, se la procedura appartiene ad un pacchetto Oracle, il pacchetto viene considerato come parte del nome della procedura. Quindi, è necessario fornire un nome dello schema ed il nome del pacchetto, nel formato:
EXTERNAL NAME "mySchema.myPackage.myProc";  

Ciò consente di scegliere dinamicamente lo schema, ma non il nome del pacchetto, nell'istruzione CALL.

Se il nome della procedura contiene caratteri wildcard SQL (carattere di percentuale % e carattere di sottolineatura _ ), il nome della procedura viene modificato dal broker in modo da includere il carattere escape del database immediatamente prima di ciascun carattere wildcard. Ciò assicura che il database riceva i caratteri wildcard come caratteri letterali. Ad esempio, supponendo che il carattere escape del database sia una barra retroversa, la clausola riportata di seguito viene modificata dal broker in modo che mySchema.Proc\_” viene passato al database. ;
EXTERNAL NAME "mySchema.Proc_";  
Per tutte le procedure esterne sono valide le seguenti limitazioni:
  • Una procedura memorizzata non può essere sovraccaricata sul database. Una procedura memorizzata è considerata sovraccaricata se esiste più di una procedura con lo stesso nome nello stesso schema del database. Se il broker rileva che una procedura è stata sovraccaricata, genera un'eccezione.
  • I parametri non possono essere del tipo di dati ESQL REFERENCE, ROW, LIST o INTERVAL.
  • I tipi definiti dall'utente non possono essere utilizzati come parametri o valori di ritorno.

Esempio di routine del database 1

Di seguito è riportato una definizione ESQL semplice di una procedura memorizzata che restituisce un valore scalare singolo ed un parametro OUT:

CREATE PROCEDURE myProc1(IN P1 INT, OUT P2 INT)
	LANGUAGE DATABASE
	RETURNS INTEGER
	EXTERNAL NAME "myschema.myproc";

Utilizzare questo codice ESQL per richiamare la routine myProc1:

/*using CALL statement invocation syntax*/
CALL myProc1(intVar1, intVar2) INTO intReturnVar3;

/*or using function invocation syntax*/
SET intReturnVar3 = myProc1(intVar1, intVar2);

Esempio di routine del database 2

Il codice ESQL riportato di seguito illustra come definire e richiamare le procedure memorizzate DB2:

ESQL Definition:
DECLARE inputParm CHARACTER;
DECLARE outputParm CHARACTER;
DECLARE inputOutputParm CHARACTER;

SET inputParm = 'Hello';
SET inputOutputParm = 'World';
CALL swapParms( inputParm, outputParm, inputOutputParm );

CREATE PROCEDURE swapParms (
  IN parm1 CHARACTER,
  OUT parm2  CHARACTER,
  INOUT parm3 CHARACTER
) EXTERNAL NAME dbSwapParms;

Per registrare questa procedura memorizzata in DB2, copiare il seguente script in un file (ad esempio, test1.sql)

-- DB2 Example Stored Procedure
DROP PROCEDURE dbSwapParms @                   
CREATE PROCEDURE dbSwapParms
( IN in_param CHAR(32), 
  OUT out_param CHAR(32),
  INOUT inout_param CHAR(32))
LANGUAGE SQL
BEGIN   
SET out_param = inout_param;  
    SET inout_param = in_param;
END @

ed eseguire:
db2 -td@ -vf test1.sql 
dal prompt dei comandi DB2.
L'esecuzione del codice dovrebbe restituire i seguenti risultati:
  • Il valore del parametro IN non cambia (e per definizione non può cambiare).
  • Il valore del parametro OUT diventa "World".
  • Il valore del parametro INOUT cambia in "Hello".

Esempio di routine del database 3

Il codice ESQL riportato di seguito illustra come definire e richiamare le procedure memorizzate Oracle:

ESQL Definition:
DECLARE inputParm CHARACTER;
DECLARE outputParm CHARACTER;
DECLARE inputOutputParm CHARACTER;

SET inputParm = 'Hello';
SET inputOutputParm = 'World';
CALL swapParms( inputParm, outputParm, inputOutputParm );

CREATE PROCEDURE swapParms (
  IN parm1 CHARACTER,
  OUT parm2  CHARACTER,
  INOUT parm3 CHARACTER
) EXTERNAL NAME dbSwapParms;

Per registrare questa procedura memorizzata in Oracle, copiare il seguente script in un file (ad esempio, test1.sql)

CREATE OR REPLACE PROCEDURE dbSwapParms  
( in_param IN VARCHAR2,
  out_param OUT VARCHAR2,
  inout_param IN OUT VARCHAR2 ) 
AS 
BEGIN 
  out_param := inout_param;
  inout_param := in_param; 
END; 
/
ed eseguire:
sqlplus <userid>/<password>  @test1.sql
L'esecuzione del codice dovrebbe restituire i seguenti risultati:
  • Il valore del parametro IN non cambia (e per definizione non può cambiare).
  • Il valore del parametro OUT diventa "World".
  • Il valore del parametro INOUT cambia in "Hello".

Esempio di routine del database 4

Il codice ESQL riportato di seguito illustra come definire e richiamare le procedure memorizzate SQL Server:

ESQL Definition:
DECLARE inputParm CHARACTER;
DECLARE outputParm CHARACTER;
DECLARE inputOutputParm CHARACTER;

SET inputParm = 'Hello';
SET inputOutputParm = 'World';
CALL swapParms( inputParm, outputParm, inputOutputParm );

CREATE PROCEDURE swapParms (
  IN parm1 CHARACTER,
  INOUT parm2  CHARACTER,
  INOUT parm3 CHARACTER
) EXTERNAL NAME dbSwapParms;

Per registrare questa procedura memorizzata in SQLServer, copiare il seguente script in un file (ad esempio, test1.sql)

-- SQLServer Example Stored Procedure 
DROP PROCEDURE dbSwapParms 
go                                                   
CREATE PROCEDURE dbSwapParms 
 @in_param     CHAR(32), 
 @out_param    CHAR(32) OUT, 
 @inout_param  CHAR(32) OUT 
AS 
  SET NOCOUNT ON
  SET @out_param   = @inout_param 
  SET @inout_param = @in_param 
go 
ed eseguire:
isql -U<userid> -P<password> -S<server> -d<datasource> -itest1.sql
Nota:
  1. SQL Server considera i parametri OUTPUT dalle procedure memorizzate come parametri INPUT/OUTPUT.

    Se tali parametri vengono dichiarati come parametri OUT nel codice ESQL, al runtime viene rilevato un errore di mancata corrispondenza del tipo. Per evitare tale mancata corrispondenza, è necessario dichiarare i parametri OUTPUT di SQL Server come INOUT nel codice ESQL.

  2. Sarebbe opportuno utilizzare, con le Procedure memorizzate SQL, l'opzione SET NOCOUNT ON, come mostrato nell'esempio precedente, per le seguenti ragioni:
    1. Per limitare la quantità di dati restituiti al broker da SQLServer.
    2. Per consentire alle serie di risultati di essere restituite correttamente.
L'esecuzione del codice dovrebbe restituire i seguenti risultati:
  • Il valore del parametro IN non cambia (e per definizione non può cambiare).
  • Il valore del parametro OUT diventa "World".
  • Il valore del parametro INOUT cambia in "Hello".

Esempio di routine del database 5

Il seguente codice ESQL dimostra come definire e chiamare le procedure SYBASE memorizzate:

ESQL Definition:
DECLARE inputParm CHARACTER;
DECLARE outputParm CHARACTER;
DECLARE inputOutputParm CHARACTER;

SET inputParm = 'Hello';
SET inputOutputParm = 'World';
CALL swapParms( inputParm, outputParm, inputOutputParm );

CREATE PROCEDURE swapParms (
  IN parm1 CHARACTER,
  INOUT parm2  CHARACTER,
  INOUT parm3 CHARACTER
) EXTERNAL NAME dbSwapParms;

Per registrare con SYBASE questa procedura memorizzata, copiare il seguente script in un file (ad esempio, test1.sql)

-- SYBASE Example Stored Procedure 
DROP PROCEDURE dbSwapParms 
go                                                   
CREATE PROCEDURE dbSwapParms 
 @in_param     CHAR(32), 
 @out_param    CHAR(32) OUT, 
 @inout_param  CHAR(32) OUT 
AS 
  SET @out_param   = @inout_param 
  SET @inout_param = @in_param 
go 
ed eseguire:
isql -U<userid> -P<password> -S<server> -d<datasource> -itest1.sql
Nota: SYBASE considera i parametri OUTPUT delle procedure memorizzate come parametri INPUT/OUTPUT.

Se tali parametri vengono dichiarati come parametri OUT nel codice ESQL, al runtime viene rilevato un errore di mancata corrispondenza del tipo. Per evitare tale mancata corrispondenza è necessario dichiarare i parametri OUTPUT di SYBASE come INOUT nel codice ESQL.

L'esecuzione del codice dovrebbe restituire i seguenti risultati:
  • Il valore del parametro IN non cambia (e per definizione non può cambiare).
  • Il valore del parametro OUT diventa "World".
  • Il valore del parametro INOUT cambia in "Hello".

Esempio di routine del database 6

Questo esempio illustra come richiamare una procedura memorizzata che restituisce due serie di risultati ed un parametro out:

CREATE PROCEDURE myProc1 (IN P1 INT, OUT P2 INT)
  LANGUAGE DATABASE
  DYNAMIC RESULT SETS 2
  EXTERNAL NAME "myschema.myproc";

Utilizzare il codice ESQL riportato di seguito per richiamare myProc1:

/* using a field reference */
CALL myProc1(intVar1, intVar2, Environment.RetVal[], OutputRoot.XML.A[])
/* using a reference variable*/
CALL myProc1(intVar1, intVar2, myReferenceVariable.RetVal[], myRef2.B[])
Concetti correlati
Panoramica di ESQL
Attività correlate
Sviluppo di ESQL
Richiamo delle procedure memorizzate
Riferimenti correlati
Diagrammi di sintassi: tipi disponibili
Istruzioni ESQL
Istruzione CALL
Tabella di associazione del tipo di dati ESQL in Java
Informazioni particolari | Marchi | Download | Libreria | Supporto | Commenti
Copyright IBM Corporation 1999, 2006 Ultimo aggiornamento: ago 17, 2006
ak04970_