动态脚本创建oracle

时间:2018-05-23 11:43:20

标签: oracle plsql oracle11g

我有一个带有基表名称及其列名的表t1。我想为每个表生成脚本,列标题由管道分隔符分隔。

create table t1 (table_nm varchar2(10) , col_nm varchar2(20));

  INSERT INTO T1  SELECT 'AAA' , 'FNAME' FROM DUAL UNION ALL
                         SELECT 'AAA' , 'LNAME' FROM DUAL UNION ALL
                         SELECT 'AAA' , 'PH_NO' FROM DUAL UNION ALL
                         SELECT 'BBB' , 'LAST_NM' FROM DUAL UNION ALL
                         SELECT 'BBB' , 'EMAIL' FROM DUAL ;
  COMMIT;

我正在尝试的代码。

 SELECT * FROM
    (
    WITH ABC AS (SELECT TABLE_NM, RTRIM(XMLAGG(XMLELEMENT(E,COL_NM,'|').EXTRACT('//text()') ORDER BY COL_NM).GETCLOBVAL(),'|') AS COL 
    from t1 group by table_nm)
     select
      'set termout off '||chr(10)|| 
      'set timing off '||chr(10)||
      'set echo off '||chr(10)||
      'set feedback off '||chr(10)||
      'set linesize 104 '||chr(10)||
      'set pagesize 0 '||CHR(10)||
      'spool /tmp/'||abc.TABLE_NM||'.csv '||CHR(10)||
      'SELECT '||''''||COL||''''||' FROM DUAL;'||CHR(30)||
      'select '||COL||' from '||abc.table_nm||';'||chr(10)||
      'spool off' EXTRACT
      FROM ABC
      );

我得到的实际数据错误。

1)ORA-00996:连接运算符是||,而不是|

预期的文件/输出

 AAA.dat
 FNAME|LNAME|PH_NO
 .... some values with pipe delimiter
 ...

 BBB.dat
 LAST_NM|EMAIL
 some values with pipe delimiter
你可以帮忙解决这个问题。

我修改了问题并删除了第一个问题。是的我不需要||在最后..我在查询中也发生了变化。在sql developer中执行上面的代码后,我得到了像

这样的输出
"set termout off 
set timing off 
set echo off 
set feedback off 
set linesize 104 
set pagesize 0 
spool /tmp/AAA.dat
SELECT 'FNAME|LNAME|PH_NO' FROM DUAL;
SELECT  FNAME|LNAME|PH_NO FROM AAA;
spool off"   

第二个select语句将错误提供为:

 SELECT  FNAME|LNAME|PH_NO FROM AAA;
 ORA-00996: the concatenate operator is ||, not |
00996. 00000 -  "the concatenate operator is ||, not |" 

有没有其他方法来处理这个问题?

1 个答案:

答案 0 :(得分:0)

第二个生成的查询使用错误的连接运算符(|而不是||):

SELECT  FNAME|LNAME|PH_NO FROM AAA;

由于您需要将分隔符本身包含在输出中,因此您需要转换为:

SELECT  FNAME || '|' || LNAME || '|' || PH_NO FROM AAA;

为此,您可以使用串联字符串(|)替换分隔符char(||'|'||)。您还需要在此处转义字符串文字中的单引号(||''|''||)。

您可以直接在生成查询中执行此操作:

...
'select '|| REPLACE(COL, '|', '||''|''||') ||' from '||abc.table_nm||';'||chr(10)||
...

更新后的整个查询:

SELECT * FROM
(
WITH ABC AS (SELECT TABLE_NM, RTRIM(XMLAGG(XMLELEMENT(E,COL_NM,'|').EXTRACT('//text()') ORDER BY COL_NM).GETCLOBVAL(),'|') AS COL 
from t1 group by table_nm)
 select
  'set termout off '||chr(10)|| 
  'set timing off '||chr(10)||
  'set echo off '||chr(10)||
  'set feedback off '||chr(10)||
  'set linesize 104 '||chr(10)||
  'set pagesize 0 '||CHR(10)||
  'spool /tmp/'||abc.TABLE_NM||'.csv '||CHR(10)||
  'SELECT '||''''||COL||''''||' FROM DUAL;'||CHR(30)||
  'select '||REPLACE(COL, '|', '||''|''||')||' from '||abc.table_nm||';'||chr(10)||
  'spool off' EXTRACT
  FROM ABC
  );