Показать полную графическую версию : .
valerarom2021
27-07-2021, 15:31
Добрый день. С помощью Invoke-Sqlcmd пытаюсь сделать, чтобы скрипт выполнял запросы сразу на нескольких SQL базах. Вот пример кода. Скрипт сохраняет в переменные строки с двух текстовых файлов.
$SQLNames = Get-Content -Path C:\komp.txt
$SQLBDs = Get-Content -Path C:\bd.txt
foreach($SQLName in $SQLNames)
{
foreach($SQLBD in $SQLBDs) {
Invoke-Sqlcmd -ServerInstance $SQLName -Username $Username -Password $Password -Database $SQLBD -Query $query -Verbose | Out-GridView
}
}
Проблема заключается в том, что $SQLName сохраняет только первую строку из файла komp.txt и пытается на одном и том же компьютере подключиться к базе из переменной $SQLBD.
Судя по приведенному коду на каждом из SQLName выполнятся ВСЕ запросы из bd.txt (или так и нужно было?)
Т.к. вывод идет в Out-GridView после выполнения запросов цикл должен остановиться и показать табличку с выводом. После закрытия таблички выполнится еще один кусок цикла. (насчет этого не уверен, не на чем протестировать).
valerarom2021
28-07-2021, 12:12
Судя по приведенному коду на каждом из SQLName выполнятся ВСЕ запросы из bd.txt (или так и нужно было?) »
Да, но почему-то SQLName парсит komp.txt только первую строку из списка. Out-GridView я планирую, чтобы не останавливал цикл, но пока не получается.
DJ Mogarych
28-07-2021, 13:05
Я бы для начала отладил выполнение запросов к нескольким базам на одной машине.
А чтобы хорошо и быстро работали запросы к нескольким серверам одновременно, рекомендую Invoke-Command (https://docs.microsoft.com/ru-ru/powershell/scripting/learn/remoting/running-remote-commands?view=powershell-7.1).
Да, но почему-то SQLName парсит komp.txt только первую строку из списка. »
valerarom2021, упакуйте Ваши komp.txt и bd.txt в архив, каковой приложите к сообщению.
valerarom2021
28-07-2021, 13:34
Я бы для начала отладил выполнение запросов к нескольким базам на одной машине. »
Я сделал выполнение запросов на одной машине. С этим проблем нет. Для работы с SQL мне больше подходит Invoke-Sqlcmd. пробовал другие варианты, мне не понравились.
valerarom2021, упакуйте Ваши komp.txt и bd.txt в архив, каковой приложите к сообщению. »
В целях безопасности я не могу это сделать. Могут только дать пример строк. Имя RXX-XXXX-N, база BDXXXXX. Только это ничего не даст. Думаю проблема в том что у меня цикл в цикле.
valerarom2021, нужен не пример строк, а кодировка текста, наличие/отсутствие BOM и вид конца строк.
valerarom2021
28-07-2021, 14:37
нужен не пример строк, а кодировка текста, наличие/отсутствие BOM и вид конца строк. »165012
valerarom2021
28-07-2021, 14:39
наличие/отсутствие BOM »
В какой кодировке лучше? сейчас UTF-8 без BOM
Первое соединение компьютер, база проходит правильно. Второй раз первая строка компьютер не меняется, только база.
DJ Mogarych
28-07-2021, 14:49
Invoke-Command - это не замена Invoke-Sqlcmd, а параллельный запуск команд сразу на нескольких машинах. Ссылочку почитайте.
Новая папка.7z »
Там по одной строке ровно в обоих файлах.
valerarom2021
28-07-2021, 15:19
Там по одной строке ровно в обоих файлах. »
165013
valerarom2021, я прогнал этот код:
$SQLNames = Get-Content -Path 'C:\Мои проекты\0346\1\komp.txt'
$SQLBDs = Get-Content -Path 'C:\Мои проекты\0346\1\bd.txt'
foreach($SQLName in $SQLNames) {
foreach($SQLBD in $SQLBDs) {
#Invoke-Sqlcmd -ServerInstance $SQLName -Username $Username -Password $Password -Database $SQLBD -Query $query -Verbose | Out-GridView
"[$SQLName]`t[$SQLBD]"
}
''
}
и закономерно убедился, что с перебором там всё в порядке.
Вы выкладывали весь Ваш код?
valerarom2021
28-07-2021, 16:04
Вы выкладывали весь Ваш код? »
$objbutton_Ok.Add_Click({
if ($objCheckBox_comp.Checked){
$SQLNames = Get-Content -Path C:\komp.txt
$SQLBDs = Get-Content -Path C:\bd.txt
foreach($SQLName in $SQLNames)
{
foreach($SQLBD in $SQLBDs)
{
Invoke-Sqlcmd -ServerInstance $SQLName -Username $Username -Password $Password -Database $SQLBD -Query $query -Verbose | Out-GridView
Write-Host соединено с $SQLName, $SQLBD
}
}
}
})
Ставлю галочку на всех компьютерах и нажимаю кнопку выполнить.
соединено с R67-356786-N DB354657. Write-Host показывает что в $SQLName парсит только первую строку, после этого база меняется, а имя пк нет.
Write-Host показывает что в $SQLName парсит только первую строку, после этого база меняется, а имя пк нет. »
У Вас есть понимание того, как работает цикл foreach и что такое массивы?
Начните с составления словесного алгоритма того, что необходимо получить...
valerarom2021
30-07-2021, 12:39
У Вас есть понимание того, как работает цикл foreach и что такое массивы? »
Да есть. Я первый раз встречаюсь с тем, что приходится делать два цикла. Вы сможете подсказать, пожалуйста ?
Начните с составления словесного алгоритма того, что необходимо получить... »
Выше я описал, что должно получиться.
Выше я описал, что должно получиться. »
Выше, Вам Iska показал:
и закономерно убедился, что с перебором там всё в порядке. »
что с циклами там всё в порядке... чем ещё можно помочь с той информацией, которую Вы показали?
Если есть необходимость получить помощь, не надо секретничать и выдавать информацию по чайной ложке в неделю. Конфиденциальную информацию можете заменить чем-нибудь или затереть...
Сделайте скриншоты результата работы Вашего скрипта, со всеми ошибками, в том числе. И сам скрипт покажите целиком, чтобы было понятно, что у вас там происходит.
Иначе никак.
Выложил весь код. »
Ну, собственно, изменим немного Ваш код, т.к. нет у меня реальных баз SQL, вот в этой части:
...
$cnt = 0
$objbutton_Ok.Add_Click({
if ($objCheckBox_opsone.Checked){SQLOLEDB}
if ($objCheckBox_ops.Checked){
$SQLNames = Get-Content -Path '.\komp.txt'
$SQLBDs = Get-Content -Path '.\bd.txt'
$query = $objText_query.Text
$Username = " "
$Password = " "
foreach($SQLName in $SQLNames){
foreach($SQLBD in $SQLBDs){
# Имитация таблицы
$tmp = [pscustomobject]@{
Комп = $SQLName
База = $SQLBD
ID = $cnt++
}
$tmp|ogv
# Т.к. реального парка компов нет, как и SQL баз, закомментируем:
#Invoke-Sqlcmd -ServerInstance $SQLName -Username $Username -Password $Password -Database $SQLBD -Query $query -Verbose | Out-GridView
Write-Host соединено с $SQLName, $SQLBD
}
write-host '----------'
}
}
})
...
и запустим этот код:
http://ipic.su/img/img7/tn/2021-7-3123-0-21.1627750928.png (http://ipic.su/img/img7/fs/2021-7-3123-0-21.1627750928.png)
То бишь, на каждую итерацию родительского цикла, приходится по одному полному проходу вложенного цикла, что собственно, в коде и записано.
Вывод:
Если у Вас работает не так, значит проблема со строкой запуска командлета Invoke-Sqlcmd, проверяйте её.
DJ Mogarych
31-07-2021, 21:48
Зачем этот графический интерфейс, занимающий миллион строк кода, когда можно было просто пару параметров сделать?
DJ Mogarych, ну, например, не умеет/не любит человек в командную строку.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.