переменные цикла застряли как постоянные при использовании sqlcmd - PullRequest
0 голосов
/ 31 августа 2018

При создании сценария bash, который вызывает sqlcmd для различных переменных в цикле, он заметил, что устанавливает переменные цикла, которые должны обновляться в цикле, на постоянную после вызова первой время (можно сказать, что это весьма вероятно, виновник по continue ing и более поздним и более поздним сегментам цикла, пока не достигнет сегмента sqlcmd). То есть. если мы перебираем список (длиной L) имен таблиц MSSQL-сервера с 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"

где файл, используемый как $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 голосов
/ 31 августа 2018

Я подозреваю, что 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...