【问题标题】:Storing CHAR or CLOB sqlplus columns into a shell script variable将 CHAR 或 CLOB sqlplus 列存储到 shell 脚本变量中
【发布时间】:2011-07-08 08:58:12
【问题描述】:

当列值包含空格时,我无法将列值存储到 shell 脚本变量中,因为所有结果都以空格而不是实际列值分割。

例如,这是我现在得到的:

set -A SQL_RESULTS_ARRAY `sqlplus -s un/pass@database << EOF
SET ECHO OFF
SET FEED OFF
SET HEAD OFF
SET SPACE 0
SELECT EMAIL_SUBJECT, MAIL_TO FROM EMAIL_TABLE;
EOF`

echo "${SQL_RESULTS_ARRAY[0]}"
echo "${SQL_RESULTS_ARRAY[1]}"

这不起作用,因为 EMAIL_SUBJECT 的值是一个完整的句子,即“消息主题测试”,所以那些回声最终会打印出来

Message
subject

代替

Message subject test
email1@email.com email2@email.com

基本上,我如何最终在数组中只有两个项目(每列一个),而不是五个项目(每个单词一个)?这完全可以通过单个连接实现吗? (我宁愿不要每列开始一个新的连接)

编辑:另一件事,我的另一个 CLOB 列是 EMAIL_BODY,它基本上可以是任何文本——因此我宁愿没有预设分隔符,因为 EMAIL_BODY 可以有各种逗号、管道、换行符,等等……

【问题讨论】:

    标签: shell unix ksh sqlplus


    【解决方案1】:

    阅读 bash 的“内部字段分隔符”$IFS

    它默认设置为空白,这可能会导致您的问题。

    【讨论】:

      【解决方案2】:

      您缺少的关键是将外壳的 IFS(内部字段分隔符)设置为与查询结果相同。这是一个 ksh 会话:

      $ results="Message subject test,email1@email.com email2@email.com"
      $ set -A ary $results
      $ for i in 0 1 2 3 4; do print "$i. ${ary[$i]}"; done
      0. Message
      1. subject
      2. test,email1@email.com
      3. email2@email.com
      4. 
      $ IFS=,
      $ set -A ary $results
      $ for i in 0 1 2 3 4; do print "$i. ${ary[$i]}"; done
      0. Message subject test
      1. email1@email.com email2@email.com
      2.
      3.
      4.
      

      你可能想做这样的事情:

      results=`sqlplus ...`
      old_IFS="$IFS"
      IFS=,
      set -A SQL_RESULTS_ARRAY $results
      IFS="$old_IFS
      print "${SQL_RESULTS_ARRAY[0]}"
      print "${SQL_RESULTS_ARRAY[1]}"
      

      【讨论】:

      • 这在我的小例子中实际上很完美,但是我的真实表中的其他列之一是 EMAIL_BODY,这会在选择一个不会意外拆分 EMAIL_BODY 的字符方面产生巨大风险,以防万一任何人决定将来在其中添加一个带有逗号(或我选择的任何字符)的条目......不过谢谢! (我会投票赞成,但我没有足够的代表:()
      • @beans:可能在这种情况下,您应该选择一个字段,然后从对偶中选择一个分隔符字符串,然后选择下一个字段,等等。因此,您将字段放在单独的块上,并且您可以使用它以正常管道方式输入。因此,您不会遇到多行字段的问题。
      • 您可以使用空字节作为分隔符:select field1 || chr(0) || field2 || chr(0) || ...。我不确定在这种情况下,对于 ksh,IFS 会是什么样子。
      【解决方案3】:

      尝试在 select 语句中使用字符串连接添加双引号。引用的数组元素允许空格(至少在 bash 中)。

      【讨论】:

      • 将查询更改为SELECT '"' || EMAIL_SUBJECT || '"', '"' || MAIL_TO || '"' FROM EMAIL_TABLE; 仍然产生这些结果:SQL_RESULTS_ARRAY[0]=("Message) SQL_RESULTS_ARRAY[1]=(subject) SQL_RESULTS_ARRAY[2]=(test") SQL_RESULTS_ARRAY[3]=("email1@email.com) SQL_RESULTS_ARRAY[4]=(email2@email.com")
      • 如果 glenn 的建议不能解决问题,我认为 sqlplus 只是不正确地填充数组,总是在不同的字段中。是否可以选择将 sqlplus 脚本的输出通过管道传输到 cutawk
      【解决方案4】:

      您可以尝试设置 COLSEP 并按其值分隔。

      【讨论】:

      • 如何将它们分开?我在数据库中将 EMAIL_SUBJECT 的值更改为“消息主题测试”并执行了“SET COLSEP”,但它没有用(但也许这不是你的意思)
      • 我也将查询更改为SELECT EMAIL_SUBJECT, (SELECT ',' FROM DUAL), MAIL_TO FROM EMAIL_TABLE;SET COLSEP ,,也没有用
      • @beans:您可以参考任何 sqlplus 参考(只需搜索 sqlplus set colsep)。 set colsep 的参数是要在列之间输出的字符串。例如,您可以像这样设置它:set colsep '---' 看看会发生什么。抱歉,没有方便的 sqlplus,因此不会提供完整的解决方案,但是一旦您为您的环境选择了一个唯一的字符串,您就可以将之前的内容与该字符串之后的内容分开。
      • @beans:或者你在shell方面有问题?然后听听 IFS 的回答。或者您可以将 awk 与 -F string. 一起使用
      猜你喜欢
      • 1970-01-01
      • 2012-06-26
      • 1970-01-01
      • 2020-01-13
      • 1970-01-01
      • 2013-07-08
      • 1970-01-01
      • 2019-03-09
      • 2017-06-13
      相关资源
      最近更新 更多