W tym artykule spróbuję pokazać sposób na przejście przez każdą bazę danych i wykonanie pewnej czynności na każdej bazie danych, jednak postaram się powstrzymywać od stosowania czystego SQL. Zadanie polegające na wykonaniu szeregu czynności dla każdej bazy są dość częste w pracy administratora. Może np. ze względu na audyt trzeba zaraportować użytkowników z każdej bazy, a może chcesz sprawdzić czy każda baza ma swój backup, a może na serwerze szukasz bazy, w której występuje określona tabela czy procedura. W każdym z tych przypadków może się przydać poniższy kawałek kodu.
Skorzystamy z SMO, na początku należy więc załadować SMO:
1 |
[Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") |
Niektórzy wynik powyższego polecenia przesyłają potokiem do Out-Null, dzięki czemu ekran nie będzie zaśmiecony komunikatem o załadowanej bibliotece. Warto z tego skorzystać zwłaszcza, jeżeli tworzony kod ma być wykorzystywany jako funkcja. Z punktu widzenia użytkownika funkcji te komunikaty to „niezrozumiały bełkot”.
Kolejny krok, który będzie się powtarzał również w następnych artykułach, więc warto go zapamiętać, to utworzenie obiektu odpowiadającego za instancję, na której chcesz pracować. U nas będzie to domyślna instancja na lokalnym komputerze. Tworzenie obiektu dokładniej pokazałem w części nr 1:
1 |
$SqlServer = New-Object -TypeName Microsoft.SqlServer.Management.SMO.Server -ArgumentList "localhost" |
alternatywnie było można to zapisać tak:
1 |
$SqlServer = New-Object Microsoft.SqlServer.Management.SMO.Server "localhost" |
lub tak:
1 |
$SqlServer = New-Object("Microsoft.SqlServer.Management.SMO.Server") "localhost" |
I właściwie już blisko rozwiązania. Bo okazuje się, że obiekt SMO.Server ma właściwość Databases (!). Wystarczy więc napisać pętlę przechodzącą przez wszystkie elementy tej kolekcji:
1 2 3 4 5 |
#display all databases (even system) foreach($sqldatabase in $SqlServer.Databases) { $sqldatabase.name } |
W tym przypadku ograniczyliśmy się do wyświetlenia tylko nazwy bazy danych. Pewnie interesuje cię jakie jeszcze właściwości ma baza danych widoczna w powershell. nic trudnego. Obiekt $sqldatabase jeszcze istnieje, więc prześlij go potokiem do Get-Member:
1 |
$sqldatabase | Get-Member |
podobnie zresztą można zrobić z $SqlServer aby zbadać jakie właściwości ma obiekt odpowiadający za cały SQL server:
1 |
$SqlServer | Get-Member |
Komplikujemy przykład. Dla każdej tabeli w każdej bazie danych chcemy wyświetlić na ekranie kropkę. Propozycja rozwiązania:
1 2 3 4 5 6 7 8 9 |
foreach($sqldatabase in $SqlServer.Databases) { $sqldatabase.name foreach($table in $sqldatabase.Tables) { Write-Host -NoNewline "." } Write-Host } |
Wyświetlić bazy danych możesz też wchodząc na wirtualny napęd SQLServer:
1 2 3 |
Import-Module sqlps cd SQLServer:\SQL\Localhost\Default\Databases Get-ChildItem |
W tym jednak przypadku… nie widać baz systemowych. Gdyby zaś chcieć wyświetlić wszystkie tabele w ramach jednej wybranej bazy danych wykonać można:
1 |
cd AdventureWorks2014 |
1 |
cd Tables |
1 |
ls |
A gdyby chcieć zobaczyć tylko tabele ze schematu Sales, dodaj wyrażenie where.
ls | where { $_.Schema -eq ‚Sales’ }
A jeśli dla każdej tabeli chcesz zobaczyć pełną ścieżkę do tabeli dodaj
ls | where { $_.Schema -eq ‚Sales’ } | select pspath
I na tym na dzisiaj kończymy. c.d.n.
Komentarze:
[…] backup dla większej ilości baz (może nawet dla wszystkich – porównaj z artykułem wykonywanie czynności dla każdej bazy danych) możesz przesyłać do Backup-SqlDatabase nazwę bazy również […]