PDA

Показать полную графическую версию : .


Страниц : [1] 2

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.

Elven
27-07-2021, 22:45
Судя по приведенному коду на каждом из 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).

Iska
28-07-2021, 13:09
Да, но почему-то 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. Только это ничего не даст. Думаю проблема в том что у меня цикл в цикле.

Iska
28-07-2021, 14:16
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, а параллельный запуск команд сразу на нескольких машинах. Ссылочку почитайте.

Iska
28-07-2021, 15:03
Новая папка.7z »
Там по одной строке ровно в обоих файлах.

valerarom2021
28-07-2021, 15:19
Там по одной строке ровно в обоих файлах. »
165013

Iska
28-07-2021, 15:45
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 парсит только первую строку, после этого база меняется, а имя пк нет.

YuS_2
28-07-2021, 18:01
Write-Host показывает что в $SQLName парсит только первую строку, после этого база меняется, а имя пк нет. »
У Вас есть понимание того, как работает цикл foreach и что такое массивы?
Начните с составления словесного алгоритма того, что необходимо получить...

valerarom2021
30-07-2021, 12:39
У Вас есть понимание того, как работает цикл foreach и что такое массивы? »
Да есть. Я первый раз встречаюсь с тем, что приходится делать два цикла. Вы сможете подсказать, пожалуйста ?
Начните с составления словесного алгоритма того, что необходимо получить... »
Выше я описал, что должно получиться.

YuS_2
30-07-2021, 14:09
Выше я описал, что должно получиться. »
Выше, Вам Iska показал:
и закономерно убедился, что с перебором там всё в порядке. »
что с циклами там всё в порядке... чем ещё можно помочь с той информацией, которую Вы показали?
Если есть необходимость получить помощь, не надо секретничать и выдавать информацию по чайной ложке в неделю. Конфиденциальную информацию можете заменить чем-нибудь или затереть...
Сделайте скриншоты результата работы Вашего скрипта, со всеми ошибками, в том числе. И сам скрипт покажите целиком, чтобы было понятно, что у вас там происходит.
Иначе никак.

YuS_2
31-07-2021, 20:06
Выложил весь код. »
Ну, собственно, изменим немного Ваш код, т.к. нет у меня реальных баз 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
Зачем этот графический интерфейс, занимающий миллион строк кода, когда можно было просто пару параметров сделать?

Iska
31-07-2021, 22:13
DJ Mogarych, ну, например, не умеет/не любит человек в командную строку.




© OSzone.net 2001-2012