我需要使用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打破它们。我真的很感激任何建议,甚至完全不同于我的方法 - 我是学习的程序员。
答案 0 :(得分: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
是一个隐藏选项,但重要的是只有一个标题
答案 1 :(得分: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;
答案 2 :(得分:0)
这是将管道分隔头添加到SQL语句的方法。一旦将其假脱机,“东西”就不会在那里
-- this creates the header
select 'ImanRelation:primary_object|ImanRelation:secondary_object|ImanRelation:relation_type' 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
...