通过bash将结果从DB2导出到CSV,包括列名

时间:2018-06-29 10:58:24

标签: bash shell db2 sh

此问题分出一个已经提出的问题。

我想使用包含列名的db2结果制作一个csv文件。

EXPORT TO ...
SELECT 1 as id, 'COL1', 'COL2', 'COL3' FROM sysibm.sysdummy1
UNION ALL
(SELECT 2 as id, COL1, COL2, COL3 FROM myTable)
ORDER BY id

这确实可行,但我留下了多余的列和1和2的行

有没有一种方法可以通过db2命令或完整的bash替代方法来实现,而没有多余的列,同时将标头保持在顶部?

例如

Column 1 Column 2 Column 3 data 1 data 2 data3 ... ... ...

代替:

1 Column 1 Column 2 Column 3 2 data 1 data 2 data3 2 ... ... ...

5 个答案:

答案 0 :(得分:0)

用于Linux / Unix / Windows的Db2缺少(很早就应该)针对此常见要求的简单选择(选择export命令)。

但是,使用bash shell,您可以运行两个单独的导出(一个用于列标题,另一个用于数据),然后通过一个中间名称管道将结果连接到文件中。

使用中间命名管道意味着您不需要数据的两个平面文件副本。

它丑陋而笨拙,但可以。

示例片段(您可以初始化变量以适合您的环境)

mkfifo ${target_file_tmp}
(( $? != 0 )) && print "\nERROR: failed to create named pipe ${target_file_tmp}" && exit 1

db2 -v "EXPORT TO ${target_file_header} of del SELECT 'COL1', 'COL2', 'COL3' FROM sysibm.sysdummy1 "

cat ${target_file_header} ${target_file_tmp} >> ${target_file} & 
(( $? > 0 )) && print "Failed to append ${target_file} . Check permissions and free space" && exit 1

db2 -v "EXPORT TO ${target_file_tmp} of del SELECT  COL1, COL2, COL3 FROM myTable ORDER BY 1 "
rc=$?
(( rc == 1 )) && print "Export found no rows matching the query" && exit 1
(( rc == 2 )) && print "Export completed with warnings, your data might not be what you expect" && exit 1
(( rc > 2 )) && print "Export failed. Check the messages from export" && exit 1

答案 1 :(得分:0)

我看到的所有答案都使用两个单独的导出语句。第一个生成列标题:

db2 "EXPORT TO /tmp/header.csv of del  
SELECT 
SUBSTR(REPLACE(REPLACE(XMLSERIALIZE(CONTENT XMLAGG(XMLELEMENT(NAME c,colname) 
ORDER BY colno) AS VARCHAR(1500)),'<C>',', '),'</C>',''),3) 
FROM syscat.columns WHERE tabschema=${SCHEMA} and tabname=${TABLE}"

然后查询正文

db2 "EXPORT TO /tmp/body.csv of del  
SELECT * FROM ${SCHEMA}.${TABLE}"

然后

cat /tmp/header.csv /tmp/body.csv > ${TABLE}.csv

答案 2 :(得分:0)

这将适合您的简单情况

EXPORT TO ...
SELECT C1, C2, C3 FROM (
SELECT 1 as id, 'COL1' as C1, 'COL2' as C2, 'COL3' as C3 FROM sysibm.sysdummy1
UNION ALL
(SELECT 2 as id, COL1, COL2, COL3 FROM myTable)
)
ORDER BY id

更长期的EXTERNAL TABLE支持(已在Db2 Warehouse中提供)具有INCLUDEHEADER选项,这是(我想)将在某个时候出现在Db2中。

答案 3 :(得分:0)

如果您只想要提取的数据的标题,并且希望这些标题始终位于最前面,并且希望能够更改这些标题的名称,以使其看起来更加用户友好并将其全部输入CSV文件。

您可以执行以下操作:

# Creates headers and new output file
HEADERS="ID,USERNAME,EMAIL,ACCOUNT DISABLED?"
echo "$HEADERS" > "$OUTPUT_FILE"

# Gets results from database 
db2 -x "select ID, USERNAME, DISABLED FROM ${SCHEMA}.USER WHERE lcase(EMAIL)=lcase('$USER_EMAIL')" | while read ID USERNAME DISABLED ;
do

  # Appends result to file
  echo "${ID},${USERNAME},${USER_EMAIL},${DISABLED}" >> "$OUTPUT_FILE"

done

不需要临时文件或合并。

答案 4 :(得分:0)

我编写了一个存储过程,该存储过程通过describe命令提取标头。可以从临时表中检索名称,并将其导出到文件中。唯一仍然不可能的是通过SQL来连接文件,因此最后一步需要同时转移到文件和重定向到另一个文件。

CALL DBA.GENERATE_HEADERS('SELECT * FORM SYSCAT.TABLES') @
EXPORT TO myfile_header OF DEL SELECT * FROM SESSION.header @
EXPORT TO myfile_body OF DEL SELECT * FORM SYSCAT.TABLES @
!cat myfile_header myfile_body > myfile @

存储过程的代码位于:https://gist.github.com/angoca/8a2d616cd1159e5d59eff7b82f672b72 有关更多信息,请访问:https://angocadb2.blogspot.com/2019/11/export-headers-of-export-in-db2.html