在创建循环中针对不同变量调用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上)。如果有人知道这是怎么回事或任何其他调试建议,请告诉我。
答案 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
的脚本中取消继承循环的标准输入重定向。