我正在尝试生成这样的plsql脚本:
set serveroutput on format word_wrapped;
DECLARE
file_name VARCHAR2(400);
varTemp NUMBER;
BEGIN
file_name := 'data_oracle.csv';
EXECUTE IMMEDIATE 'CREATE TABLE data_tmp (
ID NUMBER(25),
CLASS VARCHAR2(20),
DATE DATE,
VAL NUMBER(25)
)
ORGANIZATION EXTERNAL (
TYPE ORACLE_LOADER
DEFAULT DIRECTORY USER_DIR
ACCESS PARAMETERS (
RECORDS DELIMITED BY NEWLINE
FIELDS TERMINATED BY '',''
MISSING FIELD VALUES ARE NULL
(
ID,
CLASS,
DATE,
VAL
)
)
LOCATION (''' || file_name || ''')
)
PARALLEL 5
REJECT LIMIT UNLIMITED';
EXECUTE IMMEDIATE 'CREATE GLOBAL TEMPORARY TABLE tableTemp ON COMMIT PRESERVE ROWS AS SELECT a.ID,a.DATE,a.VAL,b.CLS,b.FEES,b.TYPE FROM data_tmp a, secondTable b WHERE a.CLASS = b.CLS AND (b.FEES < a.VAL)';
SELECT COUNT(1) INTO varTemp FROM tableTemp'; -- line 52
IF varTemp > 0 THEN
-- code to write query result to file
END IF;
END;
/
但我得到了这个例外:
SELECT COUNT(ID) INTO varTemp FROM tableTemp;
*
ERROR at line 52:
ORA-06550: line 52, column 38:
PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 52, column 1:
PL/SQL: SQL Statement ignored
但正在正确生成所有表并正在加载数据。
有人可以告诉我在第52行我做错了。请在这里帮助一位神谕新手。
答案 0 :(得分:0)
在编译时,表不存在,您在脚本中创建它。您还必须将SELECT也作为动态SQL
运行但是,我建议只使用静态文件名创建一次表。如果文件系统上的文件名不同,请考虑使用符号链接。
此外,绝对不需要在运行时动态创建GLOBAL TEMPORARY TABLE。当会话结束时,无论如何都会删除此类表的内容。
我假设你试图动态创建表data_tmp
的原因是因为file_name
正在改变(可能文件名包含当天的时间戳)。如果文件名没有改变,根本不需要动态SQL!
答案 1 :(得分:0)
最好包括创建GLOBAL TEMPORARY Table
,将查询结果写入文件的代码,作为独立于原始表创建的单独代码块。原因是它当前在代码失败时调试代码变得更加困难。
换句话说,CREATE TABLE data_tmp..
应该是一个独立的一次性sql脚本的一部分,它永久地创建外部表。
在动态sql中运行所有内容的问题在于它将编译时错误转换为运行时错误,导致它对开发人员的调试不太友好。
现在,您的问题是,您尝试运行的匿名块首先被编译以解决所有依赖项。但是,TABLE tableTemp
无法在编译时解析,因为它尚未 NOT 。避免这种情况的一种方法是将此部分包含在动态sql中。
EXECUTE IMMEDIATE 'SELECT COUNT (1) FROM tableTemp' INTO varTemp ;
完成所有操作后,请记住,最终得到的代码效率低,不便携。