2010-08-05 417 views
28

¿Alguien sabe de alguna manera, o incluso si es posible, para llamar a un procedimiento almacenado desde dentro de otro? Si es así, ¿cómo lo harías?Llamar a un procedimiento almacenado con otro en Oracle

Aquí está mi código de prueba:

SET SERVEROUTPUT ON; 

DROP PROCEDURE test_sp_1; 
DROP PROCEDURE test_sp; 

CREATE PROCEDURE test_sp 
AS 
BEGIN 
    DBMS_OUTPUT.PUT_LINE('Test works'); 
END; 
/

CREATE PROCEDURE test_sp_1 
AS 
BEGIN 
    DBMS_OUTPUT.PUT_LINE('Testing'); 
    test_sp; 
END; 
/

CALL test_sp_1; 

Respuesta

38

Sus procedimientos almacenados trabajan como Coded . El problema es con la última línea, no puede invocar ninguno de sus procedimientos almacenados.

Tres opciones en SQL * Plus son: call, exec, y un bloque de PL/SQL anónimo.

call parece ser una palabra clave SQL, y está documentada en la Referencia SQL. http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_4008.htm#BABDEHHG El diagrama de sintaxis indica que se requieren parentesis, incluso cuando no se pasan argumentos a la rutina de llamada.

CALL test_sp_1(); 

Un anónimo bloque PL/SQL es PL/SQL que no está dentro de un llamado procedimiento, una función de disparo, etc. Se puede utilizar para llamar a su procedimiento.

BEGIN 
    test_sp_1; 
END; 
/

Exec es un comando SQL * Plus que es un acceso directo para el bloque anónimo anteriormente.EXEC <procedure_name> se pasarán al servidor DB como BEGIN <procedure_name>; END;

ejemplo completo:

SQL> SET SERVEROUTPUT ON 
SQL> CREATE OR REPLACE PROCEDURE test_sp 
    2 AS 
    3 BEGIN 
    4  DBMS_OUTPUT.PUT_LINE('Test works'); 
    5 END; 
    6/

Procedure created. 

SQL> CREATE OR REPLACE PROCEDURE test_sp_1 
    2 AS 
    3 BEGIN 
    4  DBMS_OUTPUT.PUT_LINE('Testing'); 
    5  test_sp; 
    6 END; 
    7/

Procedure created. 

SQL> CALL test_sp_1(); 
Testing 
Test works 

Call completed. 

SQL> exec test_sp_1 
Testing 
Test works 

PL/SQL procedure successfully completed. 

SQL> begin 
    2  test_sp_1; 
    3 end; 
    4/
Testing 
Test works 

PL/SQL procedure successfully completed. 

SQL> 
13

Claro, usted simplemente lo llaman desde dentro de la SP, no hay una sintaxis especial.

Ex:

PROCEDURE some_sp 
    AS 
    BEGIN 
     some_other_sp('parm1', 10, 20.42); 
    END; 

Si el procedimiento es en un esquema diferente al que el procedimiento de ejecución es de, es necesario prefijar con el nombre de esquema.

PROCEDURE some_sp 
    AS 
    BEGIN 
     other_schema.some_other_sp('parm1', 10, 20.42); 
    END; 
+0

Gracias por que sin embargo cuando trato de ejecutar que el uso LLAME a sp_1; Recibo el siguiente error. de error a partir de la línea 21 al mando: LLAMADA test_sp_1 informe error: SQL error: ORA-06576: no es una función o procedimiento nombre válido 06576. 00000 - "no una función o procedimiento nombre válido" * Causa: Podría no encontrar una función (si una cláusula INTO estaba presente) o un procedimiento (si la declaración no tenía una cláusula INTO) para llamar a . * Acción: cambie la instrucción para invocar una función o procedimiento – electricsheep

+0

@Michael Lockwood: ¿Puede publicar su código en su pregunta original? Además, si llama a una función utilizando una herramienta como SQL * PLus, debe asignar el valor de retorno a una variable. – dcp

+0

@ML: ¿por qué todavía está tratando de usar CALL cuando CALL no funciona (no es una declaración PL/SQL válida) y dcp le ha mostrado cómo hacerlo correctamente? –

2

@Michael Lockwood - no es necesario que utilice la palabra clave "CALL" en cualquier lugar. Solo necesita mencionar el procedimiento directamente.

Eso es

Begin 
    proc1(input1, input2); 
end; 
/

en lugar de

Begin 
    call proc1(input1, input2); 
end; 
/
+0

Al mirar su código y el historial de revisión de la pregunta, no veo dónde está utilizando la llamada dentro de PL/SQL. La llamada está fuera de cualquier PL/SQL, y es un intento de probar los procedimientos almacenados. –

2

Para invocar el procedimiento desde la línea de comandos SQLPlus, prueba uno de estos:

CALL test_sp_1(); 
EXEC test_sp_1 
2

Calling un procedimiento desde otro procedimiento:

Uno para un procedimiento normal:

CREATE OR REPLACE SP_1() AS 
BEGIN 
/* BODY */ 
END SP_1; 

procedimiento de llamada SP_1 desde SP_2:

CREATE OR REPLACE SP_2() AS 
BEGIN 
/* CALL PROCEDURE SP_1 */ 
SP_1(); 
END SP_2; 

llamar a un procedimiento con REFCURSOR o salida del cursor:

CREATE OR REPLACE SP_1 
(
oCurSp1 OUT SYS_REFCURSOR 
) AS 
BEGIN 
/*BODY */ 
END SP_1; 

Llame al sp_1 procedimiento que devolverá el REFCURSOR como parámetro de salida

CREATE OR REPLACE SP_2 
(
oCurSp2 OUT SYS_REFCURSOR 
) AS `enter code here` 
BEGIN 
/* CALL PROCEDURE SP_1 WITH REF CURSOR AS OUTPUT PARAMETER */ 
SP_1(oCurSp2); 
END SP_2; 
+0

Ritght asnwer para oráculo. –

+0

Sirve igual si es number el out? y es necesario si o si OUT? –

Cuestiones relacionadas