Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ajax/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ORA-00984:此处不允许列-动态SQL_Sql_Oracle_Plsql_Sqlplus - Fatal编程技术网

ORA-00984:此处不允许列-动态SQL

ORA-00984:此处不允许列-动态SQL,sql,oracle,plsql,sqlplus,Sql,Oracle,Plsql,Sqlplus,这是我的包裹代码 CREATE OR REPLACE PACKAGE BODY FMSSMART.GENERIC_PURGER AS PROCEDURE GET_PARTITIONID_JULIAN (i_date IN DATE, i_number_of_partitions IN NUMBER, o_parti

这是我的包裹代码

CREATE OR REPLACE PACKAGE BODY FMSSMART.GENERIC_PURGER
AS

   PROCEDURE GET_PARTITIONID_JULIAN (i_date                   IN     DATE,
                              i_number_of_partitions   IN     NUMBER,
                              o_partitionID               OUT NUMBER)
   IS
   BEGIN
      SELECT MOD (TO_NUMBER (TO_CHAR (TO_DATE (i_date, 'YYYYMMDD'), 'j')),
                  i_number_of_partitions)
        INTO o_partitionID
        FROM DUAL;

      DBMS_OUTPUT.put_line (o_partitionID);
   END GET_PARTITIONID_JULIAN;

 PROCEDURE DELETE_TBL_SML
    (
      i_tablename IN VARCHAR2,
      o_retcode OUT NUMBER,
      o_errormsg OUT VARCHAR2
    )
     IS

    stmt VARCHAR2(1000);
    o_start_time DATE;
    o_end_time DATE;

    BEGIN
      select to_char(sysdate, 'YYYYMMDDHH24MISS') into o_start_time from dual;
      stmt := 'DELETE FROM ' ||i_tablename;
      EXECUTE IMMEDIATE stmt;
      COMMIT;
      select to_char(sysdate, 'YYYYMMDDHH24MISS') into o_end_time from dual;

    EXCEPTION WHEN OTHERS THEN
    o_retcode := SQLCODE;
    o_errormsg := substr(SQLERRM, 1, 200);


    INSERT INTO AUDIT_PROC_TBL (error_number, error_message, package_name, procedure_name, start_time, end_time) VALUES (o_retcode, o_errormsg, 'GENERIC_PURGER','DELETE_TBL_SML', o_start_time, o_end_time);
    return;
    END DELETE_TBL_SML;

 PROCEDURE INSERT_AUDIT_PROC_TBL
 (
      i_retcode IN NUMBER,
      i_errormsg IN VARCHAR2,
      i_package_name IN  VARCHAR2,
      i_procedure_name IN VARCHAR2,
      i_start_time IN DATE,
      i_end_time IN DATE
 )
   IS
    BEGIN
          EXECUTE IMMEDIATE  'INSERT INTO AUDIT_PROC_TBL (error_number, error_message, package_name, procedure_name, start_time, end_time) VALUES (i_retcode, i_errormsg, i_package_name,  i_procedure_name,i_start_time,  i_end_time)';
          COMMIT;
          RETURN;
   END INSERT_AUDIT_PROC_TBL;

END GENERIC_PURGER;
/
执行时:

set autocommit off;
set serveroutput on size 1000000;
ALTER SESSION SET NLS_DATE_FORMAT='YYYYMMDD HH24:MI:SS';
EXECUTE INSERT_AUDIT_PROC_TBL(-1, 'NA', 'GENERIC_PURGER','DELETE_TBL_SML', '20150212164527', '20150212164527');
我遇到了一个错误,它使我:

Session altered.

BEGIN INSERT_AUDIT_PROC_TBL(-1, 'NA', 'GENERIC_PURGER','DELETE_TBL_SML', '20150212164527', '20150212164527'); END;

*
ERROR at line 1:
ORA-00984: column not allowed here
ORA-06512: at "FMSSMART.INSERT_AUDIT_PROC_TBL", line 12
ORA-06512: at line 1

您得到的错误不是来自如何调用过程,而是过程在做什么。ORA-00984错误报告在FMSMART的
12行。插入审计程序TBL
程序,即:

EXECUTE IMMEDIATE  'INSERT INTO AUDIT_PROC_TBL (error_number, error_message, package_name, procedure_name, start_time, end_time) VALUES (i_retcode, i_errormsg, i_package_name,  i_procedure_name,i_start_time,  i_end_time)';
在这里,当您不需要使用动态SQL时,您正在使用动态SQL;没有任何东西动态和静态SQL都可以:

INSERT INTO AUDIT_PROC_TBL (error_number, error_message, package_name,
  procedure_name, start_time, end_time)
VALUES (i_retcode, i_errormsg, i_package_name,  
  i_procedure_name,i_start_time,  i_end_time);
不过,作为将来的参考,当您使用动态SQL时,需要为传入的值使用绑定变量;动态SQL语句中有一个用冒号表示的绑定占位符,例如
:var1
,然后用
using
子句提供实际值。目前,在原始版本中,
i_retcode
被解释为列名,而不是变量,这超出了动态上下文的范围。因此,您可以使用以下内容:

EXECUTE IMMEDIATE  'INSERT INTO AUDIT_PROC_TBL (error_number, '
  || 'error_message, package_name, procedure_name, start_time, end_time) '
  || 'VALUES (:retcode, :errormsg, :package_name,  :procedure_name, '
  || ':start_time,  :end_time)'
USING i_retcode, i_errormsg, i_package_name,  i_procedure_name,
  i_start_time,  i_end_time;
为了便于阅读,我将语句拆分为多行;通过
| |
进行连接意味着最后一个字符串与所有字符串都在一行中一样


我还有一些超出问题范围的其他意见:

  • 在会话中设置NLS_日期_格式,然后依靠隐式转换;奇怪的是,使用的格式与字符串不匹配。最好在调用中显式传递日期值,例如
    到_date('20150221264527','YYYYMMDDHH24MISS')
    或使用
    时间戳
    文字
  • DELETE\u TBL\u SML
    包中,情况更糟,因为您仍然依赖于会话NLS设置,您无法始终控制该设置,并且您显式地将日期转换为字符串,而只是隐式地将日期转换回字符串。而不是
    选择将字符(sysdate,'yyyyymmddhh24miss')从dual转换为o_start_time只需
    o\u开始时间:=sysdate)
  • 在程序中提交或回滚通常被认为是不好的做法;最好由调用方决定是否提交以及何时提交,因为它可能正在做过程不知道的其他事情,这些事情应该被视为同一事务的一部分
  • 捕获您不处理的异常,尤其是在其他异常时捕获异常通常是一个bug。尽管您在这里将代码和消息返回给调用者,但是他们必须查找它。让异常传播回调用方几乎总是更好的,调用方也可以反馈到提交/回滚决策中
删除程序可简化为:

PROCEDURE DELETE_TBL_SML(i_tablename IN VARCHAR2) IS
  o_start_time DATE;
  o_end_time DATE;
BEGIN
  o_start_time := sysdate;
  EXECUTE IMMEDIATE 'DELETE FROM ' ||i_tablename;
  o_end_time := sysdate;

  INSERT INTO AUDIT_PROC_TBL (error_number, error_message, package_name,
    procedure_name, start_time, end_time)
  VALUES (SQLERRCODE, substr(SQLERRM, 1, 200), 'GENERIC_PURGER',
    'DELETE_TBL_SML', o_start_time, o_end_time);
END DELETE_TBL_SML;

除非您只想审核错误,在这种情况下,您需要将execute包含在它自己的子块中;然后将其命名为
exec fmsmart.GENERIC\u PURGER.DELETE\u TBL\u SML()

为什么要使用动态SQL进行审计插入?我使用动态SQL进行审计插入,因为它不仅限于遇到的错误。嗨,Alex,非常感谢,你解决了我的问题。我也是这个pl/sql的初学者,现在,我可以执行这个sql了,它是成功的。ALTER SESSION SET NLS_DATE_FORMAT='yyyyymmdd HH24:MI:SS';执行插入“审计程序待审查(-1,'不适用','通用'清除','删除'待审查'SML','20150221274829','20150221274829');嗨,亚历克斯,你能帮我修改一下我在DELETE_TBL_SML中的代码吗?我这个软件包有点问题。Thanks@LelanCalusay-你应该为一个新问题问一个新问题。我可以看到一些事情可能没有按照您想要的方式运行,但是您需要显示如何调用它以及您得到的输出/错误,这值得提出自己的问题。好的,我应用了您的建议,它在不使用NLS\U DATE\U格式的情况下为我提供了一个很好的结果。。设置自动提交关闭;执行INSERT_AUDIT_PROC_TBL(-1,'NA','GENERIC_PURGER','DELETE_TBL_SML',to_date('20150221283731','YYYYMMDDH24MISS'),to_date('2015022128732','YYYYMMDDH24MISS');看来,我得等两天再问另一个问题。也许我应该把代码贴在这里