2017-06-04 16 views
0

我分配了以下任务。创建一个表格,其中动态PL/SQL中的'日期条件'

假设我们有一个表A由一个id列和一个日期列构成。 在PL/SQL中编写一个过程:以表名(在本例中为A)和日期D作为参数,创建一个名为A_bck的备份表,仅包含A日期为< D的记录,并从表A中删除all插入A_bck中的记录。

Here there is my code.

不幸我得到这个错误:

Error report - 
ORA-00904: "MAY": invalid identifier 
ORA-06512: at line 41 
ORA-06512: at line 80 
00904. 00000 - "%s: invalid identifier" 

如果我尝试使用id列WHERE条件而不是上的日期一个以达到相同的结果,我没有问题。 错误在哪里?我是否完全以错误的方式执行它?

+0

这听起来像日期格式模型问题。到目前为止你做了什么? – eaolson

+1

外部链接可能不适用于所有人。 – Nitish

回答

1

你的问题是,当你正在执行动态SQL你查询建立为一个字符串。 Oracle不知道你给出的日期实际上是一个日期,它只是被视为字符串的一部分。为了解决这个问题,你应该能够做到以下几点:

my_query := 'CREATE TABLE ' || table_name_backup || ' AS (SELECT * FROM ' || table_name || ' WHERE table_date < to_date(''' || backup_date || '''))';

这应该理清您的问题给你。作为一个附注,你可能会想改变你的“table_exists”查询,因为表名都以大写形式存储,例如,

SELECT COUNT(*) INTO table_exists FROM USER_TABLES WHERE TABLE_NAME = upper(my_table);

编辑:进一步说明如下评论

要解释为什么您使用整数的时候没有上述问题,但要记住,使用立即执行只是执行给定的字符串作为一个很重要SQL查询。

例如:

select 1 from dual where 1 = 1

这是完全有效的SQL:在上面的例子

declare 
    x INTEGER := 1; 
    i integer; 
    my_query VARCHAR2(256); 
begin 
    my_query := 'select 1 from dual where 1 = ' || x; 
    EXECUTE IMMEDIATE my_query INTO i; 
end; 

my_query将作为被执行。

CREATE TABLE abaco_bck AS (SELECT * FROM abaco WHERE table_date < 27-MAY-17)

,因为它不是用引号引用,或显式转换为日期,SQL引擎正在试图减去“可以”从:然而,在你的榜样,你有这样的事情结束了27,但它不知道“可能”是什么。

另一件要提及的是,对于某些操作,您可以使用绑定变量而不是引号(尽管您不能用于DDL),例如

declare 
    lToday DATE := SYSDATE; 
    i   INTEGER; 
    my_query VARCHAR2(256); 
begin 
    my_query := 'select 1 from dual where sysdate = :1'; 
    EXECUTE IMMEDIATE my_query INTO i USING lToday; 
end; 
+0

现在一切都合情合理!所以,每次我需要创建一个动态SQL语句时,不是字符串的变量都必须用''转义。我错误地认为这个连接是自动完成的。但为什么如果变量是一个数字,我没有得到任何错误? – peppe

+0

增加了一些更多的解释,希望为你增加一些解释 – Chrisrs2292

+0

很好的解释。我稍微偏好''where table_date