需要将带有换行符的字符串从 Unix shell 脚本传递到 sql 查询

Need to pass string with newline character from Unix shell script to sql query

我正在使用 unix shell KSH 脚本来做一些 table 清理工作。 我有一个文件 "partner.txt" 有 5000 行,像这样

>cat partner.txt

aaa0000
aaa0001
aaa0002
...
...
aaa5000

使用这个文件,我应该清理几个 tables 与匹配,比如合作伙伴的协议。 因此,我正在构建一个合作伙伴列表字符串,其格式可以在 sql 语句中使用 'IN' 子句(select * from tab where partner IN partner_list)

('aaa0000',
'aaa0001','aaa0002',...,'aaa0010',
'aaa0011','aaa0012',...,'aaa0020',
...
'aaa4990','aaa4991',...,'aaa5000')

我像这样将字符串分配给 partner_list 变量。

export BO="("
export BC=")"
export BQ="('"
export QC="','"
export QB="')"
export  C=","
export CE=","'\n'
export QCE="',"'\n'"'"

partnerListLine=${BO}
while read partnerline;
do
    if [ `expr ${counter} % 10` -eq 0 ]
    then
        partnerListLine=${partnerListLine}${partnerline}${CE}

    elif [ ${counter} -lt ${numOfObsoletePartner} ]
    then
        partnerListLine=${partnerListLine}${partnerline}${C}
    fi 
    counter=`expr ${counter} + 1`
done < partner.txt
partnerListLine=${partnerListLine}${partnerline}${BC}

然后我使用这个合作伙伴列表来获取我的协议列表,例如

SQL_agreement='select distinct a.agreement from partner_agreement_map a where a.partner in ${partner_list} order by agreement asc;'

我需要在合作伙伴列表中添加换行符,因为我使用的是 sqlplus 并遇到 SP2-0027:输入太长(> 2499 个字符) 我通过在 N partners

之后将以下内容附加到我的合作伙伴列表字符串来添加换行符
CE=","'\n'

当我在脚本中直接使用 sqlplus 时,这工作正常。

但是当我尝试将此 partner_list 字符串作为参数传递给 sql 脚本时,它在查询中显示“\n”。

这就是我调用 sql 脚本并传递参数的方式

sqlplus -s ${REFERENCE_DB_USER}/${REFERENCE_DB_PASS}@${DATABASE_INSTANCE} << !!
set serveroutput on size 10000;
set feedback off;
set verify off;
set echo off;
set term off;
set pagesize 0;
SET linesize 1000;
SET TRIMSPOOL ON;

spool  1_del_agreement_spool_$$.lst;

@1_del_agreement.sql ${partner_list};

spool off;

exit;
/
!!

这是我的假脱机文件

>cat 1_del_agreement_spool_18165.lst                                   <

select distinct a.agreement from partner_agreement_map a where a.partner in ('aaa0000',\n'aaa0001','aaa0002','aaa0003',...'aaa0010',\n'aaa0011'...) order by agreement asc
                                                                                    *
ERROR at line 1:
ORA-00907: missing right parenthesis

当我将参数传递给 sql 脚本而不将其替换为 '\n' 时,如何保持换行符? 我试过 ANSI-C 引用但失败了。

如果您需要 shell 或 sql 脚本的更多详细信息,请告诉我

如果您使用的是 bash,您可以使用 $'\n' 来打印换行符,这将使您的示例成为

if [ `expr ${counter} % 10` -eq 0 ]
then
    partnerListLine=${partnerListLine}${partnerline}"',"$'\n'"'"
else
    ...

示例:

$ echo hello"',"$'\n'"'"
hello',
'

我没有可行的解决方案,但提示:'\n' 表示 "insert the literal backslash followed by n"。所以你告诉 shell 不要管这个字符串。

尝试 NL=$(echo -e '\n') 或类似的方法来获取实际上包含换行符的字符串变量。然后你可以定义CE=",$NL"

shell 可能会在处理字符串时保留这个换行符。

或者使用像 awk 这样的工具来创建一个带换行符的字符串值,你用 partner_list=$(awk ...) 分配给 partner_list 以防止 shell 做任何类型的值的处理。

如果这不起作用,您可能必须将数据写入文件(使用新行)。

更新了我的整个解决方案设计

试了一晚上,我放弃了。 感谢 Aaron 和 mplf 的投入。

我决定将我的解决方案从基于文件更改为基于table。我将读取 partner.txt 文件并将合作伙伴插入虚拟临时文件 table。然后我可以轻松地对其他 table 进行查询。

事实上,我认为这应该是我的第一个设计:) 在之前的设计中我可能遗漏了一些非常小的东西。但无论如何,这会容易得多 我希望我的团队领导审查设计而不是代码格式问题 :P