Хранимая процедура не дает того же результата при вызове от разработчика PL / SQL и SQL* плюс - PullRequest
1 голос
/ 06 февраля 2020

Я пытаюсь вызвать процедуру из сценария оболочки, используя sql* плюс, но у меня возникает странная проблема.

Моя процедура начинается с загрузки данных в курсор из таблицы. Затем для каждой строки курсора он вызывает другую процедуру, которая должна вставить данные в другую таблицу. После этого он обновляет строки, считанные из первой таблицы, для добавления метки времени "work done".

Когда я вызываю эту процедуру из PL / SQL Developer, все работает нормально, и я передаю свои данные в второй стол. Когда я вызываю ту же самую процедуру из sql* plus, она говорит мне, что все работает нормально (возвращает 0), добавляется метка времени работы, но я не получаю данных, вставленных во вторую таблицу.

Я в недоумении относительно того, что может быть причиной этого.

Вот строка, используемая в скрипте для вызова процедуры:

echo exit | sqlplus -S $schema @call_to_procedure.sql 

$ схема - схема / pwd@db

call_to_procedure. sql is

set serveroutput on feedback off
declare
  V_RETURN number(1);
begin
  SCHEMA.PACKAGE.PROCEDURE(V_RETURN);
  dbms_output.put_line(V_RETURN);
end;
/

А вот код процедуры (надеюсь, я не удалил слишком много, но в основном то, что пропало, это фильтры запроса выбора курсора)

PROCEDURE MYPROC (v_result out NUMBER) IS
    v_id_smth number(10);
    v_id_smthelse number(10);
    v_data varchar2(10);
    v_errmsg CLOB;

    CURSOR data_to_load IS
        SELECT t1.id_smth as id_smth, t1.data as data, t2.smthelse as smthelse
        FROM t1, t2
        WHERE t1.id_smth = t2.id_smth
        AND other controls
    ;

BEGIN
    FOR data in data_to_load
    LOOP
        v_id_smth := data.id_smth;
        v_id_smthelse := data.id_smthelse;
        v_data := data.data; -- sorry about that renaming scheme :/

        BEGIN
            INSERT_DATA_INTO_OTHER_TABLE(v_id_smth, v_id_smthelse, v_data);
        END;
    END LOOP;

    UPDATE T1
    SET date_processing = SYSDATE
    WHERE date_processing IS NULL;

    v_result = 0;

EXCEPTION
    WHEN OTHER THEN
    v_errmsg := SQLCODE || '-' || SQLERRM || '; v_id_smth : ' || v_id_smth || '; v_id_smthelse : ' || v_id_smthelse;
    LOG_PACKAGE.LOG_PROC('MY_PROC', v_errmsg);
    v_result := 1;

END MYPROC;

изменить для уточнения: Обе процедуры находятся в одной и той же схеме / пакете, и я вошел в систему как владелец схемы в обоих случаях (PL Developper & sql* plus) .

Ответы [ 2 ]

2 голосов
/ 06 февраля 2020

Скорее всего, проблема в переменных среды и настройках национального календаря. Вот простой пример, когда день недели 4 или 5, в зависимости от национального календаря. Например, файл bat

set NLS_LANG=AMERICAN_RUSSIA.CL8MSWIN1251
(
echo  connect  / as sysdba
echo  @E:\upwork\stackoverflow\bat_sql\sqltest.sql
echo exit
)| sqlplus   /nolog

E: \ upwork \ stackoverflow \ bat_sql \ sqltest. sql

select to_char(sysdate,'D') from dual;

Вывод

SQL*Plus: Release 11.2.0.4.0 Production on Thu Feb 6 22:53:20 2020

Copyright (c) 1982, 2013, Oracle.  All rights reserved.

SQL> Connected.


SQL>
T
-
4

изменить на AMERICA в NLS_LANG

set NLS_LANG=AMERICAN_AMERICA.CL8MSWIN1251
(
echo  connect  / as sysdba
echo  @E:\upwork\stackoverflow\bat_sql\sqltest.sql
echo exit
)| sqlplus   /nolog

E: \ upwork \ stackoverflow \ bat_sql \ sqltest. sql

 select to_char(sysdate,'D') from dual;

Вывод:

SQL*Plus: Release 11.2.0.4.0 Production on Thu Feb 6 22:56:42 2020

Copyright (c) 1982, 2013, Oracle.  All rights reserved.

SQL> Connected.

SQL>
T
-
5
1 голос
/ 06 февраля 2020

Другой вариант, кто вы входите как тот же на SQL Плюс как SQL Разработчик? Если процедура создается с правами INVOKER, разные учетные записи пользователей, выполняющих ее, могут иметь разные результаты в зависимости от их прав доступа - что может быть неочевидно, особенно если процедура подавляет исключения.

...