【问题标题】:dynamic scripts creation oracle动态脚本创建 oracle
【发布时间】:2018-05-23 11:43:19
【问题描述】:

我有一个表 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  FNAME|LNAME|PH_NO FROM AAA;
 ORA-00996: the concatenate operator is ||, not |
00996. 00000 -  "the concatenate operator is ||, not |" 

还有其他方法可以解决这个问题吗?

【问题讨论】:

  • 这应该有助于您解决第一个错误。那里的答案中发布了一些解决方法。不过,第二个错误不太清楚。具体什么时候发生?
  • 如何构建查询,如 select FNAME||'|'||LNAME||'|'||PH_NO FROM T1 如上所述。
  • 连接运算符是||,所以如果你需要创建一个文字varchar,你可以使用这样的东西:SELECT 'FNAME'||'|'||'LNAME'||'|'||'PH_NO' FROM DUAL;。如果您需要从表中选择文字值,则需要用相应的列替换它们。
  • 实际上第一个语句给出了标题列,第二个应该给出这些列的实际值,问题在于我无法动态生成字符串的第二个查询。从 DUAL 中选择“FNAME|LNAME|PH_NO”;选择 FNAME||'|'||LNAME||'|'||PH_NO||'|'||来自 AAA; FNAME|LNAME|PH_NO ROBIN|MEI|902837
  • 我已经修改了问题并发布了第二期。

标签: oracle plsql oracle11g


【解决方案1】:

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

SELECT  FNAME|LNAME|PH_NO FROM AAA;

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

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

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

可以直接在生成查询中进行:

...
'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
  );

【讨论】:

    猜你喜欢
    • 2020-01-13
    • 1970-01-01
    • 2019-03-06
    • 2015-01-31
    • 2023-03-09
    • 2013-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多