请有人帮助一个非常新手甲骨文的人。我在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命令,则会得到相同的错误消息。
任何人都知道我做错了什么?
感谢您的帮助
答案 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;操作