2008-11-04 2 views
8

В oracle я хочу создать delete sproc, который возвращает целое число в зависимости от результата удаления.oracle procedure возвращает целое число

Это то, что у меня есть до сих пор.

create or replace 
PROCEDURE Testing 
( 
iKey IN VARCHAR2 
) 
AS 

BEGIN 
    delete from MyTable WHERE 
    TheKey = iKey; 

END Testing; 

Я попытался поставить RETURNS INTEGER, но sproc не будет компилироваться.

ответ

2

Использование функции и неявная SQL курсор, чтобы определить количество строк удалены

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

BEGIN 
    delete from MyTable WHERE 
    TheKey = iKey; 

    RETURN SQL%ROWCOUNT; 

END Testing; 

Это должно работать

16

Процедура не возвращает значение. Функция возвращает значение, но вы не должны делать DML в функции (иначе вы не можете делать такие вещи, как ссылка на функцию в выражении SQL, вы путаете разрешения, так как обычно администраторы баз данных хотят иметь доступ к доступу только для чтения ко всем функциям, чтобы пользователи последовательно выполняли вычисления и т. д.).

Вы можете добавить параметр OUT в процедуру, чтобы вернуть статус. Если «успех» означает, что один или несколько строки были обновлены, вы можете использовать SQL% ROWCOUNT для подсчета числа строк, модифицированных предварительного заявлением SQL и использовать его для заполнения возвращаемого параметра, т.е.

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; 

Конечно, с точки зрения ясности общего кода, я сомневаюсь в параметрах OUT, которые, кажется, пытаются вернуть код состояния. Вы, как правило, гораздо лучше обслуживаете, допуская успех и бросая исключения в случае ошибки.

0

Возможно, вы, скорее всего, ищете функцию.

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; 

Примечание: Где я работаю, мы обычно помещаем функции внутри пакета sql.

+0

2 выбирает плюс удаление? Используйте метод SQL% ROWCOUNT, предложенный stjohnrow. – 2008-11-04 18:08:18

+0

Это довольно круто. Не знал об этом. Это определенно лучше. – 2008-11-04 18:12:14

5

Вы можете использовать хранимую процедуру для возврата результатов.

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

    oRes := SQL%ROWCOUNT; 
END; 

Для вызова используйте процедуры что-то вроде:

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

SQL%ROWCOUNT только возвращает значение сразу после DML его значение будет сброшено, если другой DML выполняется.

Чтобы обойти эту проблему, как я выполнял удаления в цикле я выдал следующую команду после DML:

row_count := row_count + SQL%ROWCOUNT; 

Пожалуйста, убедитесь, что вы объявить и инициализировать row_count := 0;

Смежные вопросы