在使用sqlplus打印csv文件时,如何进行标题格式设置。

7
我需要使用sqlplus从Oracle的表中溢出一个csv文件。下面是所需的格式:
"HOST_SITE_TX_ID","SITE_ID","SITETX_TX_ID","SITETX_HELP_ID"
"664436565","16","2195301","0"
"664700792","52","1099970","0"

以下是我编写的 shell 脚本的相关部分:
sqlplus -s $sql_user/$sql_password@$sid << eof >> /dev/null
    set feedback off
    set term off
    set linesize 1500
    set pagesize 11000
  --set colsep ,
  --set colsep '","'
    set trimspool on
    set underline off
    set heading on
  --set headsep $
    set newpage none


    spool "$folder$filename$ext"
    select '"'||PCL_CARRIER_NAME||'","'||SITETX_EQUIP_ID||'","'||SITETX_SITE_STAT||'","'||SITETX_CREATE_DATE||'","'||ADVTX_VEH_WT||'"'
    from cvo_admin.MISSING_HOST_SITE_TX_IDS;
    spool off

我使用了一些注释语句来表示我尝试过但无法正常工作的内容。

我收到的输出是:

'"'||PCL_CARRIER_NAME||'","'||SITETX_EQUIP_ID||'","'||SITETX_SITE_STAT||'","'||SITETX_CREATE_DATE||'","'||ADVTX_VEH_WT||'"'
"TRANSPORT INC","113","00000000","25-JAN-13 10.17.51 AM",""
"TRANSPORT INC","1905","00000000","25-JAN-13 05.06.44 PM","0"

这段文字表明标题出现了问题 - 实际上是打印了整个字符串,本应被解释为SQL语句,这也是显示的数据的情况。
我正在考虑如下选项:
1)使用colsep
set colsep '","'
spool
select * from TABLE
spool off

这会引入其他问题,比如数据可能存在前导和尾随空格,文件中的第一个和最后一个值没有用引号括起来。
    HOST_SITE_TX_ID","   SITE_ID"
    "             12345","      16"
    "             12345","      21

我得出结论,这种方法比我之前描述的方法更加令人烦恼。
2) 获取文件并使用正则表达式修改标题。
3) 完全离开标题,并手动在文件开头添加一个标题字符串,使用脚本。
选项2更可行,但我仍然想问一下,是否有更好的方法来格式化标题,使其成为常规csv(逗号分隔,双引号包围)格式。
我希望尽可能少地进行硬编码——我要导出的表格大约有40列,并且我目前正在运行大约400万条记录的脚本——将它们分成每个批次约10K。 我非常感谢任何建议,甚至与我的方法完全不同-我是一名学习中的程序员。
4个回答

5

如果您只需要一个标题的csv文件,一种简单的方法是执行以下操作:

set embedded on
set pagesize 0
set colsep '|'
set echo off
set feedback off
set linesize 1000
set trimspool on
set headsep off

"嵌入式"embedded"是一个隐藏选项,但仅使用一个标题非常重要。


3
我很难看出这是如何回答这里提出的问题。 - Andrew Barber
这怎么算是一个答案?他明确说了并且我确认,添加colsep并不总是有效的。 - Sam B

3
这是我创建头部的方法:

这是我创建标题的方法:

set heading off

/* header */
SELECT '"'||PCL_CARRIER_NAME||'","'||SITETX_EQUIP_ID||'","'||SITETX_SITE_STAT||'","'||SITETX_CREATE_DATE||'","'||ADVTX_VEH_WT||'"'
FROM
(
        SELECT  'PCL_CARRIER_NAME'   AS PCL_CARRIER_NAME
        ,       'SITETX_EQUIP_ID'    AS SITETX_EQUIP_ID
        ,       'SITETX_SITE_STAT'   AS SITETX_SITE_STAT
        ,       'SITETX_CREATE_DATE' AS SITETX_CREATE_DATE
        ,       'ADVTX_VEH_WT'       AS ADVTX_VEH_WT
        FROM    DUAL
)
UNION ALL
SELECT '"'||PCL_CARRIER_NAME||'","'||SITETX_EQUIP_ID||'","'||SITETX_SITE_STAT||'","'||SITETX_CREATE_DATE||'","'||ADVTX_VEH_WT||'"'
FROM
(
        /* first row */
        SELECT  to_char(123)                    AS PCL_CARRIER_NAME
        ,       to_char(sysdate, 'yyyy-mm-dd')  AS SITETX_EQUIP_ID
        ,       'value3'                        AS SITETX_SITE_STAT
        ,       'value4'                        AS SITETX_CREATE_DATE
        ,       'value5'                        AS ADVTX_VEH_WT
        FROM    DUAL
        UNION ALL
        /* second row */
        SELECT  to_char(456)                     AS PCL_CARRIER_NAME
        ,       to_char(sysdate-1, 'yyyy-mm-dd') AS SITETX_EQUIP_ID
        ,       'value3'                         AS SITETX_SITE_STAT
        ,       'value4'                         AS SITETX_CREATE_DATE
        ,       'value5'                         AS ADVTX_VEH_WT
        FROM    DUAL
) MISSING_HOST_SITE_TX_IDS;

1
在Oracle 19中,您可以使用set markup csv on来确保创建csv输出。
您还可以设置分隔符和可选引号,甚至可以选择spool html。
您可以在此处阅读更多信息:这里
set markup csv on
spool "$folder$filename$ext"
select q'|wow, I can't beleive he said "hello, how are you?", can you beleive it!|' as text 
  from dual;
spool off
quit;

1
这是如何在SQL语句中添加管道分隔的标题。一旦你将其拖出来,那个“something”就不会在那里了。
-- this creates the header
select 'header_column1|header_column2|header_column3' as something
From dual
Union all
-- this is where you run the actual sql statement with pipes in it
select 
rev.value1 ||'|'||
rev.value2 ||'|'|| 
'related_Rel' as something
from
...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接