Oracle sql存储过程数据参数丢失单引号

时间:2015-02-10 15:34:55

标签: oracle stored-procedures

请有人帮助一个非常新手甲骨文的人。我在Oracle中创建了一个存储过程来删除日期范围分区。我用来创建过程的代码是:

SQL> CREATE OR REPLACE PROCEDURE NEW_EVENT_DELETE(palterdate in VARCHAR2) AS
  2  begin
  3  execute immediate 'ALTER TABLE ROSUSER.EVENT DROP PARTITION FOR(TO_DATE(palterdate, ''DD-MON-YYYY'')) UPDATE INDEXES';
  4  end NEW_EVENT_DELETE;
  5  /

这编译得很好,但是当我尝试使用以下命令运行该程序时

exec NEW_EVENT_DELETE('03-FEB-2014');

它回来了:

ERROR at line 1:
ORA-14755: Invalid partition specification for FOR VALUES clause.
ORA-06512: at "ROSUSER.NEW_EVENT_DELETE", line 3
ORA-06512: at line 1

如果我使用命令:

ALTER TABLE ROSUSER.EVENT DROP PARTITION FOR(TO_DATE('03-FEB-2014', 'DD-MON-YYYY'));

然后它的工作原理。在我看来,输入日期周围的单引号集正在丢失,因为如果我尝试在日期周围没有引号的情况下运行ALTER命令,则会得到相同的错误消息。

任何人都知道我做错了什么?

感谢您的帮助

4 个答案:

答案 0 :(得分:2)

在处理引用引号时,我总是更喜欢这种格式:

execute immediate q'[ALTER TABLE ROSUSER.EVENT DROP PARTITION FOR(TO_DATE(']' || palterdate || q'[', 'DD-MON-YYYY')) UPDATE INDEXES]';

甚至:

  lv_sql := q'[ALTER TABLE ROSUSER.EVENT DROP PARTITION FOR(TO_DATE('<palterdate>', 'DD-MON-YYYY')) UPDATE INDEXES]';
  lv_sql := REPLACE(lv_sql, '<palterdate>', palterdate);
  execute immediate lv_sql;

答案 1 :(得分:1)

你并没有在执行中立即正确传递。将其更改为:

execute immediate 'ALTER TABLE ROSUSER.EVENT DROP PARTITION FOR(TO_DATE('''||palterdate||''', ''DD-MON-YYYY'')) UPDATE INDEXES'

你需要考虑sql注入,因为这段代码可能会被劫持。

答案 2 :(得分:1)

或者,请查看EXECUTe IMMEDIATE的USING选项

execute immediate 'ALTER TABLE ROSUSER.EVENT DROP PARTITION FOR(TO_DATE(:palterdate, ''DD-MON-YYYY'')) UPDATE INDEXES' USING palterdate;

而且,对于SQL-Injection担心,对palterdate进行快速检查可能会解决大多数问题。难以在11个字符中嵌入额外的声明! ;)

答案 3 :(得分:0)

如果你这样写引号?

1 CREATE OR REPLACE PROCEDURE NEW_EVENT_DELETE(palterdate in VARCHAR2) AS 
2 begin 
3 execute immediate 'ALTER TABLE ROSUSER.EVENT DROP PARTITION FOR(TO_DATE('''||palterdate||''', ''DD-MON-YYYY'')) UPDATE INDEXES'; 
4 end NEW_EVENT_DELETE; 
5 /

说明:3为什么引用?一个逃避另一个,一个最后连接

编辑:抱歉,我使用了&#39; +&#39;连接,因为我认为它是在SQl服务器上,你必须使用&#39; ||&#39;操作