2013-02-08 68 views
1

下面是确定表是否存在然后删除/创建表的PL/SQL脚本。如果它不存在,反正创建表。所以,当我跑的剧本,我收到了以下:如何使用EXECUTE IMMEDIATE语句纠正PL/SQL脚本中的ORA-00904错误?

ORA-00904:“E”:无效的标识符

我认为语法准确和双引号“E”是正确,但显然,不是。请指教。

谢谢。

DECLARE 

    l_cnt NUMBER; 

BEGIN 
    SELECT COUNT(*) 
    INTO l_cnt 
    FROM dba_tables 
    WHERE owner = 'ABCD' 
    AND table_name = 'SEC_REC_TEMP'; 

    IF(l_cnt > 0) 
    THEN 
    EXECUTE IMMEDIATE 'DROP TABLE sec_rec_temp'; 
    EXECUTE IMMEDIATE 'CREATE TABLE sec_rec_temp 
         AS 
         SELECT is.inv_num 
          FROM abcd.inv_summ is 
           ,abcd.bill_fee bf 
         WHERE is.inv_num = bf.inv_num 
          AND trim(bf.fee_type) = "E" 
         GROUP BY is.inv_num'; 
    ELSE 
    EXECUTE IMMEDIATE 'CREATE TABLE sec_rec_temp 
         AS 
         SELECT is.inv_num 
          FROM abcd.inv_summ is 
           ,abcd.bill_fee bf 
         WHERE is.inv_num = bf.inv_num 
          AND trim(bf.fee_type) = "E" 
         GROUP BY is.inv_num'; 
    END IF; 
END; 
/

回答

3

首先,删除并重新创建表的PL/SQL脚本非常值得怀疑。例如,你真的确定你不想创建一个定期刷新的物化视图吗?在PL/SQL中执行DDL几乎总是一个糟糕的方法。如果您可以解释您正在尝试解决的业务问题,那么我们可以向您提供更好的技术解决方案。其次,如果你想在PL/SQL中的字符串中单引号转义,你需要使用两个连续的单引号。没有一个双引号字符。

DECLARE 
    l_cnt NUMBER; 
BEGIN 
    SELECT COUNT(*) 
    INTO l_cnt 
    FROM dba_tables 
    WHERE owner = 'ABCD' 
    AND table_name = 'SEC_REC_TEMP'; 

    IF(l_cnt > 0) 
    THEN 
    EXECUTE IMMEDIATE 'DROP TABLE sec_rec_temp'; 
    EXECUTE IMMEDIATE 'CREATE TABLE sec_rec_temp 
         AS 
         SELECT is.inv_num 
          FROM abcd.inv_summ is 
           ,abcd.bill_fee bf 
         WHERE is.inv_num = bf.inv_num 
          AND trim(bf.fee_type) = ''E'' 
         GROUP BY is.inv_num'; 
    ELSE 
    EXECUTE IMMEDIATE 'CREATE TABLE sec_rec_temp 
         AS 
         SELECT is.inv_num 
          FROM abcd.inv_summ is 
           ,abcd.bill_fee bf 
         WHERE is.inv_num = bf.inv_num 
          AND trim(bf.fee_type) = ''E'' 
         GROUP BY is.inv_num'; 
    END IF; 
END; 

或者,您可以用q引用语法

DECLARE 
    l_cnt NUMBER; 
BEGIN 
    SELECT COUNT(*) 
    INTO l_cnt 
    FROM dba_tables 
    WHERE owner = 'ABCD' 
    AND table_name = 'SEC_REC_TEMP'; 

    IF(l_cnt > 0) 
    THEN 
    EXECUTE IMMEDIATE 'DROP TABLE sec_rec_temp'; 
    EXECUTE IMMEDIATE q'[CREATE TABLE sec_rec_temp 
         AS 
         SELECT is.inv_num 
          FROM abcd.inv_summ is 
           ,abcd.bill_fee bf 
         WHERE is.inv_num = bf.inv_num 
          AND trim(bf.fee_type) = 'E' 
         GROUP BY is.inv_num]'; 
    ELSE 
    EXECUTE IMMEDIATE q'[CREATE TABLE sec_rec_temp 
         AS 
         SELECT is.inv_num 
          FROM abcd.inv_summ is 
           ,abcd.bill_fee bf 
         WHERE is.inv_num = bf.inv_num 
          AND trim(bf.fee_type) = 'E' 
         GROUP BY is.inv_num]'; 
    END IF; 
END; 
2

你需要用另一个单引号

AND trim(bf.fee_type) = ''E'' 
逃单引号