首页 > 解决方案 > 从 PL/SQL 开发人员和 SQL*plus 调用时,存储过程的结果不同

问题描述

我正在尝试使用 sql*plus 从 shell 脚本调用一个过程,但我遇到了一个奇怪的问题。

我的过程首先将数据从表中加载到游标中。然后,对于游标的每一行,它调用另一个应该将数据插入另一个表的过程。之后,它更新从第一个表中读取的行以包含“工作完成”时间戳。

当我从 PL/SQL Developer 调用此过程时,一切正常,我将数据放入第二个表中。当我从 sql*plus 调用相同的过程时,它告诉我一切正常(返回 0),添加了“工作完成”时间戳,但我没有将数据插入到第二个表中。

我不知道是什么原因造成的。

这是脚本中用于调用该过程的行:

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

$schema 是 schema/pwd@db

call_to_procedure.sql 是

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)。

标签: bashoraclestored-proceduressqlplus

解决方案


最有可能的是,问题出在环境变量和国家日历设置中。这是一个简单的例子,当星期是 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

在 NLS_LANG 中更改为 AMERICA

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

推荐阅读