如何编写 SQL 语句,将带有自定义分隔符的 select、replace 和 order by 的结果假脱机到 csv 文件

问题描述 投票:0回答:1

我正在尝试完全按照问题所述操作:从表中选择,替换列中的特殊字符,对结果进行排序,然后使用自定义分隔符将其假脱机到

.csv
文件。

我只能使用sqlplus来实现此目的,并将脚本保存到文件中,通过

@filename
调用该文件。

以下是我在没有 order by 子句的情况下工作的内容

SPOOL 'comparisonPrdIZ/TB_PROV_HEADER_PART1.csv';
SELECT '"SERIAL_NO"<Sep>"PROV_HEADER"' FROM DUAL
UNION ALL
SELECT '"' ||SERIAL_NO|| '"<Sep>"'
||REPLACE(REPLACE(REPLACE(SUBSTR(PROV_HEADER,1,2000), CHR(10), ''), CHR(34),
'inchORspace'), CHR(44), '')|| '"' 
FROM TABLE;
SPOOL OFF;

什么不起作用并引发错误

ORA-00904:“SERIAL_NO”:无效标识符错误

SPOOL 'comparisonPrdIZ/TB_PROV_HEADER_PART1.csv';
SELECT '"SERIAL_NO"<Sep>"PROV_HEADER"' FROM DUAL
UNION ALL
SELECT '"' ||SERIAL_NO|| '"<Sep>"'
||REPLACE(REPLACE(REPLACE(SUBSTR(PROV_HEADER,1,2000), CHR(10), ''), CHR(34),
'inchORspace'), CHR(44), '')|| '"' 
FROM TABLE 
ORDER BY SERIAL_NO;
SPOOL OFF;
sql oracle sqlplus
1个回答
1
投票

您正在尝试对

union
的整体结果进行排序,而不仅仅是第二个分支中的查询。联合查询没有名为
SERIAL_NO
的列 - 第二个分支独立运行,但是一旦它位于联合中,它就没有了。它有效:

SELECT *
FROM (
  SELECT '"SERIAL_NO"<Sep>"PROV_HEADER"' FROM DUAL
  UNION ALL
  SELECT '"' ||SERIAL_NO|| '"<Sep>"'
  ||REPLACE(REPLACE(REPLACE(SUBSTR(PROV_HEADER,1,2000), CHR(10), ''),   CHR(34),
  'inchORspace'), CHR(44), '')|| '"' 
  FROM TABLE 
)
ORDER BY SERIAL_NO;

因此只有列表达式可用于排序。但您可能无论如何都不想这样做,因为您的标题行将包含在排序中。你可以让它工作,但是......

当您使用 SQL*Plus 时,有两个更简单的选项。

运行两个查询:

SELECT '"SERIAL_NO"<Sep>"PROV_HEADER"' FROM DUAL;

SELECT '"' ||SERIAL_NO|| '"<Sep>"'
||REPLACE(REPLACE(REPLACE(SUBSTR(PROV_HEADER,1,2000), CHR(10), ''), CHR(34),
'inchORspace'), CHR(44), '')|| '"' 
FROM TABLE 
ORDER BY SERIAL_NO;

或使用

prompt
作为标题行:

PROMPT "SERIAL_NO"<Sep>"PROV_HEADER"

SELECT '"' ||SERIAL_NO|| '"<Sep>"'
||REPLACE(REPLACE(REPLACE(SUBSTR(PROV_HEADER,1,2000), CHR(10), ''), CHR(34),
'inchORspace'), CHR(44), '')|| '"' 
FROM TABLE 
ORDER BY SERIAL_NO;

您可能需要

set embed on
以避免它们之间出现空行;并且您可能想使用
sqlplus
'silent' 标志运行
-s

© www.soinside.com 2019 - 2024. All rights reserved.