2008-11-04 9 views
8

En Oracle, quiero crear un sproc de eliminación que devuelva un número entero en función del resultado de la eliminación.procedimiento de oráculo devuelve número entero

esto es lo que tengo hasta ahora.

create or replace 
PROCEDURE Testing 
( 
iKey IN VARCHAR2 
) 
AS 

BEGIN 
    delete from MyTable WHERE 
    TheKey = iKey; 

END Testing; 

He intentado poner un INTEGER DEVUELTO pero el sproc no se compilará.

Respuesta

2

Usar una función y el cursor de SQL implícita para determinar el número de filas eliminadas

create or replace 
FUNCTION Testing 
( 
iKey IN VARCHAR2 
) RETURN INTEGER 
AS 

BEGIN 
    delete from MyTable WHERE 
    TheKey = iKey; 

    RETURN SQL%ROWCOUNT; 

END Testing; 

que debería funcionar

+0

ORA-14551: no se puede realizar una operación DML dentro de una consulta – Benoit

+0

@Benoit que es como debería ser, la función está destinada a invocarse desde PL/SQL no SQL simple – stjohnroe

16

Un procedimiento no devuelve un valor. Una función devuelve un valor, pero no debería estar haciendo DML en una función (de lo contrario, no puede hacer cosas como referenciar la función en una declaración de SQL, confunde concesiones de permisos ya que normalmente los DBA desean otorgar acceso de acceso de solo lectura a los usuarios). a todas las funciones para que los usuarios hagan cálculos de forma consistente, etc.).

Puede agregar un parámetro OUT al procedimiento para devolver el estado. Si el "éxito" significa que uno o más filas se han actualizado, puede utilizar% ROWCOUNT de SQL para obtener un recuento del número de filas modificadas por la instrucción SQL antes y usarlo para poblar el parámetro de retorno, es decir

CREATE OR REPLACE PROCEDURE test_proc (
    p_iKey IN VARCHAR2, 
    p_retVal OUT INTEGER 
) 
AS 
BEGIN 
    DELETE FROM myTable 
    WHERE theKey = p_iKey; 

    IF(SQL%ROWCOUNT >= 1) 
    THEN 
    p_retVal := 1; 
    ELSE 
    p_retVal := 0; 
    END IF; 
END test_proc; 

Por supuesto, desde el punto de vista de la claridad general del código, tengo dudas sobre los parámetros de OUT que parecen estar intentando devolver un código de estado. En general, es mucho mejor atendido al asumir el éxito y lanzar excepciones en caso de error.

0

Probablemente esté buscando una función.

FUNCTION TESTING (iKEY IN VARCHAR2) RETURN NUMBER 
IS 
    v_count NUMBER; 
    yourNumber NUMBER; 
BEGIN 

    SELECT COUNT(*) INTO v_count 
    FROM MyTable 
    WHERE TheKey = iKey; 

    IF v_count > 0 
    THEN 
     DELETE FROM MyTable 
     WHERE TheKey = iKey; 

     SELECT COUNT(*) INTO v_count 
     FROM MyTable 
     WHERE TheKey = iKey; 

     IF (v_count = 0) 
     THEN 
      yourNumber := 1; --means successful deletion 
     END IF; 
    ELSE 
     yourNumber := 0; --means no items to delete 
    END IF; 
    return yourNumber; 

    EXCEPTION 
     WHEN OTHERS THEN 
     RETURN -1; --means error was encountered 
END TESTING; 

Nota: Donde trabajo generalmente ponemos funciones dentro de un paquete sql.

+0

2 selecciona más el eliminar? Use el método SQL% ROWCOUNT sugerido por stjohnrow en su lugar. –

+0

Eso es genial. No sabia sobre eso. Eso es definitivamente mejor. –

5

Se puede utilizar un procedimiento almacenado para devolver resultados.

CREATE OR REPLACE PROCEDURE testing (iKey IN VARCHAR2, oRes OUT NUMBER) 
AS 
BEGIN 
    DELETE FROM MyTable 
     WHERE TheKey = iKey; 

    oRes := SQL%ROWCOUNT; 
END; 

Para llamar al procedimiento de uso algo como:

DECLARE 
    pRes NUMBER; 
BEGIN 
    testing ('myspecialkey', pRes); 
    DBMS_OUTPUT.put_line (pRes); 
END; 
0

El SQL%ROWCOUNT sólo devolverá un valor inmediatamente después de un LMD su valor se restablecerá si se ejecuta otra LMD.

Para evitar el problema, ya que se estaba ejecutando eliminaciones en un bucle I emitió el siguiente comando después de la LMD:

row_count := row_count + SQL%ROWCOUNT; 

Por favor asegúrese de declarar e inicializar row_count := 0;

Cuestiones relacionadas