使用 sqlcmd 时循环变量固定为常量

lam*_*ter 3 bash sqlcmd

在创建一个sqlcmd在循环中调用不同变量的 bash 脚本时,注意到它似乎将在第一次调用时应在循环中更新的循环变量设置为常量(可以看出这很可能是罪魁祸首)continueing 以及循环的后面和后面的部分,直到到达该sqlcmd部分)。IE。如果我们用 循环遍历 MSSQL Server 表名的列表(长度为 L)sqlcmd,则循环将执行,而不是 L,而是仅使用列表中的 第一个条目进行循环指令的无限迭代。

一个最小的例子如下:

#!/bin/bash

tables_list=$1

while read -r line
do
    tablecols="$line"
    IFS=',' read -a arr_tablecols <<< "$tablecols"

    mssql_tablename=${arr_tablecols[0]}

    echo -e "\n\n\n##### Processing: $mssql_tablename #####\n"

    TO_SERVER_ODBCDSN="-D -S <ODBC DSN name for mssql host>"
    TO_SERVER_IP="-S <my mssql host IP>"
    DB="ClarityETL_test"
    TABLE="$mssql_tablename"
    USER=<my mssql username>
    PASSWORD=<my mssql login password>

    #uncomment to see that sqlcmd does in fact appear to be the problem
    #continue

    {
    echo -e "Counting destination table: $DB/$TABLE"
    sqlcmd -Q "PRINT '$mssql_tablename';" \
        $TO_SERVER_ODBCDSN \
        -U $USER -P $PASSWORD \
        -d $DB
    } || { echo -e "\nFailed to truncate MSSQL DB"; exit 255; } 

done < "$tables_list"
Run Code Online (Sandbox Code Playgroud)

正在使用的文件$table_list看起来像

mymssqltable1
mymssqltable2
...
Run Code Online (Sandbox Code Playgroud)

(由于该示例仅使用该PRINT命令,因此该列表实际上可以是您想要使用的任何内容)。

这种行为对我来说真的很奇怪,在文档中找不到任何提到这一点的内容(https://learn.microsoft.com/en-us/sql/linux/quickstart-install-connect-red-hat?view=sql- server-2017#create-and-query-data)(我在 CentOS 7 上)。如果有人知道这里发生了什么或有任何进一步的调试建议,请告诉我。

Bar*_*mar 5

我怀疑sqlcmd正在从标准输入读取,因此它正在消耗输入文件的其余部分。我不确定为什么这会导致循环无限重复,而不是在第一次迭代后结束。但如果发生这种情况,解决方案是重定向 的输入sqlcmd

sqlcmd -Q "PRINT '$mssql_tablename';" \
    $TO_SERVER_ODBCDSN \
    -U $USER -P $PASSWORD \
    -d $DB < /dev/null
Run Code Online (Sandbox Code Playgroud)

当您重定向 while 循环的输入时,循环内的所有命令都会继承该重定向的输入。因此请注意,如果您sqlcmd从嵌套在循环中的另一个脚本中调用(而不是直接在循环本身内),您将执行类似的操作

while read -r line
do
    tablecols="$line"
    IFS=',' read -a arr_tablecols <<< "$tablecols"

    mssql_tablename=${arr_tablecols[0]}

    bash scriptThatUsesSqlcmd.sh mssql_tablename < /dev/null

done < "$tables_list" 
Run Code Online (Sandbox Code Playgroud)

在将使用的脚本中取消继承循环的标准输入重定向sqlcmd