web-dev-qa-db-ja.com

sqlplusでcsvファイルをスプールする際のヘッダーのフォーマット

Sqlplusを使用して、Oracleのテーブルからcsvをスプールする必要があります。必要な形式は次のとおりです。

"Host_SITE_TX_ID","SITE_ID","SITETX_TX_ID","SITETX_HELP_ID"
"664436565","16","2195301","0"
"664700792","52","1099970","0"

以下は、私が書いたシェルスクリプトの関連部分です。

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のバッチに分割します。私のアプローチとはまったく異なっていても、どんな提案でも本当にありがたいです-私は学習のプログラマーです。

6
Tech_Coder

ヘッダーが1つだけのcsvを作成する簡単な方法の1つは、次のことです。

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

embeddedは非表示のオプションですが、ヘッダーを1つだけ持つことが重要です

6
higuita

これが私がヘッダーを作成した方法です:

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;
3
the_slk