使用sqlcmd

时间:2018-08-31 01:13:46

标签: bash sqlcmd

在创建循环中针对不同变量调用sqlcmd的bash脚本时,请注意,它似乎将应在循环中更新的循环变量设置为恒定第一次调用(可以通过continue ing以及循环的更高版本和更高版本直到到达sqlcmd段来判断这是罪魁祸首)。就是如果我们使用sqlcmd遍历一列(长度为L的)MSSQL Server表名,则该循环将执行,而不是L,而是循环指令 infinite 次迭代,使用列表中只有第一个条目

下面是一个最小的示例:

#!/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"

用作$table_list的文件看起来像

mymssqltable1
mymssqltable2
...

(由于该示例仅使用了PRINT命令,因此列表实际上可能是您想使用的任何东西)。

这种行为对我来说真的很奇怪,并且在文档(https://docs.microsoft.com/en-us/sql/linux/quickstart-install-connect-red-hat?view=sql-server-2017#create-and-query-data)中找不到提及此的任何内容(我在CentOS 7上)。如果有人知道这是怎么回事或任何其他调试建议,请告诉我。

1 个答案:

答案 0 :(得分:2)

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

sqlcmd -Q "PRINT '$mssql_tablename';" \
    $TO_SERVER_ODBCDSN \
    -U $USER -P $PASSWORD \
    -d $DB < /dev/null

当您重定向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" 

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