Показать полную графическую версию : .
valerarom2021
01-08-2021, 08:57
Зачем этот графический интерфейс, занимающий миллион строк кода, когда можно было просто пару параметров сделать? »
Скриптом не только я буду пользоваться.
DJ Mogarych
01-08-2021, 09:12
Можно организовать общение с пользователем через командную строку, задавая вопросы или предоставляя выбор из пунктов. Это сильно сэкономит объём кода и силы для его написания.
valerarom2021
02-08-2021, 09:18
Если у Вас работает не так, значит проблема со строкой запуска командлета Invoke-Sqlcmd, проверяйте её. »
Вы ведете на скрине во второй строке цифры в имени компьютера и базы должны совпадать. У вас меняется только название базы. В этом проблема.
DJ Mogarych
02-08-2021, 09:40
Сколько там баз?
Уберите вложенный foreach с базами и сделайте несколько строк Invoke-Sqlcmd, прописав там имена баз в явном виде.
Будет так работать?
Вы ведете на скрине во второй строке цифры в имени компьютера и базы должны совпадать. У вас меняется только название базы. В этом проблема. »
Следовательно, представления о том, как работают циклы, у Вас нет.
Именно, для такого случая, рекомендовал:
Начните с составления словесного алгоритма того, что необходимо получить... »
Ибо то, что находится в шапке топика, это не словесный алгоритм, а код (полного понимания которого у Вас нет, видимо кто-то вам его написал) с краткими комментариями, которые ничего не объясняют.
Напишите, что в итоге требуется получить. Составьте вручную результирующие строки, которые покажут, как именно должен осуществляться доступ к базам.
valerarom2021
02-08-2021, 10:36
Сколько там баз? »
50 баз
Будет так работать? »
Так работает.
Ибо то, что находится в шапке топика, это не словесный алгоритм, а код (полного понимания которого у Вас нет, видимо кто-то вам его написал) с краткими комментариями, которые ничего не объясняют.
Напишите, что в итоге требуется получить. Составьте вручную результирующие строки, которые покажут, как именно должен осуществляться доступ к базам. »
Этот код я сам написал.
Следовательно, представления о том, как работают циклы, у Вас нет. »
Я написал много скриптов используя foreach. Все они работают. Здесь проблема в том, что оба цикла вместе не корректно работают.
DJ Mogarych
02-08-2021, 11:39
Сами по себе вложенные циклы работают нормально.
$servers = 1..5 |% {"server$($_.ToString("00"))"}
$dbs = 1..3 |% {"db$($_.ToString("00"))"}
foreach ($server in $servers) {
foreach ($db in $dbs) {
"Invoke-Sqlcmd -server $server -database $db"
}
}
Invoke-Sqlcmd -server server01 -database db01
Invoke-Sqlcmd -server server01 -database db02
Invoke-Sqlcmd -server server01 -database db03
Invoke-Sqlcmd -server server02 -database db01
Invoke-Sqlcmd -server server02 -database db02
Invoke-Sqlcmd -server server02 -database db03
Invoke-Sqlcmd -server server03 -database db01
Invoke-Sqlcmd -server server03 -database db02
Invoke-Sqlcmd -server server03 -database db03
Invoke-Sqlcmd -server server04 -database db01
Invoke-Sqlcmd -server server04 -database db02
Invoke-Sqlcmd -server server04 -database db03
Invoke-Sqlcmd -server server05 -database db01
Invoke-Sqlcmd -server server05 -database db02
Invoke-Sqlcmd -server server05 -database db03
Выведите команды с помощью echo на экран, чтобы проверить, правильно ли подставляются переменные.
Возможно, следовало бы базы перечислять в самом запросе и делать один запрос на хост, чем заниматься ковровой бомбардировкой хоста 50-ю запросами.
valerarom2021
02-08-2021, 11:55
Выведите команды с помощью echo на экран, чтобы проверить, правильно ли подставляются переменные. »
$SQLName парсит только первую строку из файла komp.txt, foreach($SQLName in $SQLNames) не отрабатывает.
Здесь проблема в том, что оба цикла вместе не корректно работают. »
О том и речь, что циклы работают именно так, как они и должны работать, т.е. как раз, корректно. Другое дело, что Вы их используете не так, как необходимо для достижения результата, который Вам требуется. А вот то, что именно требуется, непонятно тем, у кого Вы попросили помощь... либо объясните, либо подождите, возможно, у кого-то обострятся экстрасенсорные способности. :)
Вам же не отказывают в помощи, но любая задача решается быстрее, если правильно составить её условия...
$SQLName парсит только первую строку из файла komp.txt »
Переменная ничего не парсит. В переменной содержится массив того, что считывает из файла командлет get-content, так записано в Вашем коде.
А вот в цикле происходит разбор того, что записано в массиве. Ещё раз: циклы отрабатывают ровно так, как и должны. Просто Вы недопонимаете, что содержат переменные в каждой итерации каждого цикла.
valerarom2021
02-08-2021, 12:14
Переменная ничего не парсит. В переменной содержится массив того, что считывает из файла командлет get-content, так записано в Вашем коде.
А вот в цикле происходит разбор того, что записано в массиве. Ещё раз: циклы отрабатывают ровно так, как и должны. Просто Вы недопонимаете, что содержат переменные в каждой итерации каждого цикла. »
$SQLNames = Get-Content -Path C:\komp.txt
Get-Content сохраняет строки в массив $SQLNames. Дальше с коллекцией работает foreach. В данном случает в массиве только первая строка из файла komp.txt, а их там 50.
Получается имя компьютера не меняется, только обновляется переменная $SQLBDs. В итоге скрипт на одном компьютере пытается соединиться с базами со списка bd.txt Надеюсь сейчас понятно. Объяснил.
Как мне сделать чтобы массивы $SQLNames, $SQLBDs совпадали так ? например: R76-356785-N DB352785, следующее R76-356787-N DB352787
Либо используя один текстовый файл считывать сразу R76-356785-N DB352785
Получается имя компьютера не меняется, только обновляется переменная $SQLBDs. »
Не так. У родительского цикла свои итерации, у вложенного свои. На каждую итерацию родительского цикла приходится полный цикл итераций вложенного цикла. Таким образом, имя компьютера меняется, но на каждое имя компьютера будет приходиться весь массив наименований баз. Видимо, Вы хотели не этого...
Как мне сделать чтобы массивы $SQLNames, $SQLBDs совпадали так ? »
Для этого, необходимо выполнение двух условий:
1. На каждый компьютер должна приходиться одна база
2. Порядок следования компьютеров должен полностью совпадать с порядком следования соответствующих компьютерам баз.
т.е. в файлах должно быть записано так:
Файл Компьютеры:
Comp1
Comp2
Comp3
Файл Базы:
Baza1
Baza2
Baza3
- если всё именно так, то разбор массивов будет возможен одним циклом:
for ($i=0;$i -lt $SQLNames.length;$i++){
#Здесь Ваша строка запроса с соответствующими параметрами
#переменные используются так: $SQLNames[$i] и $SQLBDs[$i]
write-host $($SQLNames[$i] + ' - ' + $SQLBDs[$i])
}
Ну, или для надежности, создайте CSV файл:
Comp,Baza
Comp1,Baza1
Comp2,Baza2
Comp3,Baza3
и потом, всё в том же цикле for:
$array = Import-Csv list.csv
for ($i=0;$i -lt $array.length;$i++){
#Здесь Ваша строка запроса с соответствующими параметрами
#переменные используются так: $array.comp[$i] и $array.baza[$i]
write-host $($array.comp[$i] + ' - ' + $array.baza[$i])
}
- как-то так.
Как мне сделать чтобы массивы $SQLNames, $SQLBDs совпадали так ? например: R76-356785-N DB352785, следующее R76-356787-N DB352787 »
:shot: :shot: :shot:.
YuS_2, снимаю шляпу за настойчивость!
valerarom2021
02-08-2021, 13:06
YuS_2 »
Спасибо огромное. Именно это я и пытался сделать. Просто не сталкивался с подобным. Буду изучать дальше.
DJ Mogarych
02-08-2021, 13:41
Как мне сделать чтобы массивы $SQLNames, $SQLBDs совпадали так ? например: R76-356785-N DB352785, следующее R76-356787-N DB352787 »
Ну ёлы-палы... Уметь правильно объяснить - полдела.
valerarom2021
10-08-2021, 13:39
Добрый день. Пытаюсь улучшить скрипт. Добавить в скрипт runspace.
function runspace {
$SQLNames = Get-Content -Path "$env:userprofile\Desktop\SQL\komps.txt"
$SQLBDs = Get-Content -Path "$env:userprofile\Desktop\SQL\bd.txt"
$query = $objText_query.Text
$Username = ""
$Password = ""
$runspace = [runspacefactory]::CreateRunspace()
$runspace.Open()
$powershell = [powershell]::Create()
$powershell.Runspace = $runspace
$powershell.AddScript({
for ($i = 0; $i -lt $SQLNames.length; $i++){
Invoke-Sqlcmd -ServerInstance $SQLNames[$i] -Database $SQLBDs[$i] -Query $query -Username $Username -Password $Password -QueryTimeout 0 -Verbose
Write-Host $($SQLNames[$i] + ' - ' + $SQLBDs[$i])
}
})
$powershell.BeginInvoke()
}
$objbutton_Ok.Add_Click({
if ($objCheckBox_ops.Checked){runspace}
})
Функция runspace при нажатии кнопки не запускается. Без runspace всё работает.
Пытаюсь улучшить скрипт. »
Улучшить что именно? для чего Вам там ранспейсы?
Функция runspace при нажатии кнопки не запускается. »
там не функция не запускается... переменные-параметры внутрь ранспейсов необходимо передавать особым методом, там о них ничего не известно...
Почитайте несколько частей (https://devblogs.microsoft.com/scripting/beginning-use-of-powershell-runspaces-part-1/) на предмет изучения ранспейсов
valerarom2021
10-08-2021, 17:44
Улучшить что именно? для чего Вам там ранспейсы? » Для того, чтобы параллельно запускать скрипты sql.
valerarom2021
17-08-2021, 14:19
там не функция не запускается... переменные-параметры внутрь ранспейсов необходимо передавать особым методом, там о них ничего не известно...
Почитайте несколько частей на предмет изучения ранспейсов »
Спасибо. Прочитал статью. Сделал примерно также.
function SQLALLDB {
$SQLNames = Get-Content -Path ""
$SQLBDs = Get-Content -Path ""
$query = $objText_query.Text
$Username = ""
$Password = ""
$Code = {
$Parameters = @{
Param1 = '$SQLNames'
Param2 = '$SQLBDs'
Param3 = '$query'
Param4 = '$Username'
Param5 = '$Password'
}
for ($i = 0; $i -lt $SQLNames.length; $i++){
Invoke-Sqlcmd -ServerInstance $SQLNames[$i] -Database $SQLBDs[$i] -Query $query -Username $Username -Password $Password -MaxCharLength 100000 -
QueryTimeout 0 -Verbose
Write-Host $($SQLNames[$i] + ' - ' + $SQLBDs[$i])
}
}
[runspacefactory]::CreateRunspacePool()
$SessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
$RunspacePool = [runspacefactory]::CreateRunspacePool(1,100)
$PowerShell = [powershell]::Create()
$PowerShell.RunspacePool = $RunspacePool
$RunspacePool.Open()
[void]$PowerShell.AddScript($Code).AddArgument($Parameters)
$PowerShell.BeginInvoke()
}
Всё равно не передаются переменные. Я добавил переменные в $Parameters и изменил строку void]$PowerShell.AddScript($Code).AddParameters($Parameters)
valerarom2021
17-08-2021, 14:35
$Code = {
param($SQLNames,$SQLBDs,$query,$Username,$Password)
for ($i = 0; $i -lt $SQLNames.length; $i++){
Invoke-Sqlcmd -ServerInstance $SQLNames[$i] -Database $SQLBDs[$i] -Query $query -Username $Username -Password $Password -MaxCharLength 100000 -
QueryTimeout 0 -Verbose
Write-Host $($SQLNames[$i] + ' - ' + $SQLBDs[$i])
}
}
[runspacefactory]::CreateRunspacePool()
$SessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
$RunspacePool = [runspacefactory]::CreateRunspacePool(1,100)
$PowerShell = [powershell]::Create()
$PowerShell.RunspacePool = $RunspacePool
$RunspacePool.Open()
[void]$PowerShell.AddScript($Code).AddArgument($SQLNames).AddArgument($SQLBDs).AddArgument($query).AddArgu ment($Username).AddArgument($Password)
$PowerShell.BeginInvoke()
Такой вариант тоже не работает для меня.
Всё равно не передаются переменные. »
Такой вариант тоже не работает для меня. »
Это говорит о том, что читать надо ещё... смысл того, как именно, параметры передаются, видимо, Вы не уловили...
Начните от простого к сложному... создайте небольшой пул ранспейсов с одним или двумя параметрами без циклов внутри, запустите их, протестируйте и потом уже усложняйте.
Здесь, у Вас я вижу, что пытаетесь запустить, в каждом пространстве из пула, полный цикл размерностью длины базы. А параметры пытаетесь передать изнутри скриптблока... естественно, так ничего не будет работать.
Например, попробуйте выполнить в консоли это:
if ($Parameters){rv -n Parameters}
$Code = {
$Parameters = @{
Param1 = '1'
Param2 = '2'
Param3 = '3'
}
}
$Parameters
затем вот это:
if ($Parameters){rv -n Parameters}
$Parameters = @{
Param1 = '1'
Param2 = '2'
Param3 = '3'
}
$Parameters
- там будет наглядно видна разница
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.
Available in ZeroNet 1osznRoVratMCN3bFoFpR2pSV5c9z6sTC