Centrum Skryptów -Systemy Operacyjne

Jak dodać rekord do bazy danych, używając składni Windows PowerShell?

Udostępnij na: Facebook

Skrypciarze odpowiadają na Wasze pytania

Witamy w rubryce TechNet, w której Skrypciarze z firmy Microsoft odpowiadają na częste pytania dotyczące używania skryptów w administracji systemu. Jeśli macie jakieś pytania z tej dziedziny, zachęcamy do wysłania e-maila na adres: scripter@microsoft.com. Nie możemy zagwarantować odpowiedzi na każde otrzymane pytanie, ale staramy się jak możemy.

Jak dodać rekord do bazy danych, używając składni Windows PowerShell?

Cześć, Skrypciarze! Jakiś czas temu pokazaliście, jak można wykorzystać składnię Microsoft PowerShell do pobrania danych z bazy danych programu Microsoft Access. Próbuję obecnie dodać dane do bazy danych za jej pomocą, ale skrypt mi jakoś nie chce zadziałać. Czy wiesz może, jak się dodaje taki rekord, używając składni Windows PowerShell?

-- AB

Cześć, AB! Zanim zaczniemy, oto treść karty, jaką otrzymaliśmy w piątek 11 stycznia od Joela Thoresona:

„Dziś 11 stycznia. Chciałbym więc złożyć na Wasze ręce życzenia zdrowia, satysfakcji z pracy oraz wszystkiego, co się szczęściem zwie. Szczęśliwego Dnia Skrypciarza!!!”.

Dzięki, Joel! Cieszy nas, że pamiętała chociaż jedna osoba, bo Skrypciarskie Matki oraz Synowie najwidoczniej zapomnieli, czekałem na jakiś odzew aż do dzisiaj…

Przestałem czekać, bo nagle uświadomiłem sobie, że przecież chyba nigdy Was nie powiadomiłem, że właśnie 11 stycznia przypada międzynarodowy Dzień Skrypciarza. Jesteście usprawiedliwieni, nie dotyczy to jednak matek i synów, oni wiedzieli…

Jeżeli oczywiście chcenie przysłać nam jakiś spóźniony prezent, przesyłki prosimy kierować na poniższy adres:

Microsoft Corporation

One Microsoft Way

Building 42/4039

Redmond, WA 99352

Pamiętacie powiedzenie „lepiej późno niż wcale”?

Skoro więc lepiej późno niż wcale, oto skrypt, który dodaje nowe rekordy do bazy danych programu Access za pomocą niczego innego, jak tylko składni Windows PowerShell (można także dodać rekord lub inną bazę danych, która korzysta z ADO.) Domyślamy się, ze niektórzy z Was próbowali użyć języka VBScript, który korzysta z ADO, a następnie przekonwertować go na skrypt Windows PowerShell z tymi samymi zadaniami do wykonania. Można to oczywiście zrobić, jest tu jednak wiele pułapek, na które natknął się z pewnością AB. Zaraz je omówimy, teraz jednak zaserwujemy Wam cały skrypciarski tort:

$adOpenStatic = 3

$adLockOptimistic = 3



$objConnection = New-Object -com "ADODB.Connection"

$objRecordSet = New-Object -com "ADODB.Recordset"



$objConnection.Open("Provider = Microsoft.Jet.OLEDB.4.0; Data Source = C:\Scripts\Test.mdb")



$objRecordset.Open("Select * From Computers", $objConnection,$adOpenStatic,$adLockOptimistic)



$objRecordSet.AddNew()

$objRecordSet.Fields.Item("ComputerName").Value = "atl-ws-001"

$objRecordSet.Fields.Item("SerialNumber").Value = "192ATG43R"

$objRecordSet.Update()



$objRecordSet.Close()

$objConnection.Close()

Jak widzicie, zaczynamy od nadania wartości zmiennym $adOpenStatic oraz $adLockOptimistic:

$adOpenStatic = 3

$adLockOptimistic = 3

Nie będziemy dziś za bardzo rozwodzić się nad nimi, wystarczy powiedzieć, że to właśnie one pomagają określić typ kursora oraz blokowanie rekordów używane podczas otwierania tabeli w bazie danych (jeżeli potrzebujecie bardziej szczegółowych informacji na ten temat, to pomocny może okazać się webcast Database Scripting For System Administrators (j.ang.)). Naszym kolejnym krokiem będzie utworzenie wystąpień obiektów ADODB.Connection oraz ADODB.Recordset:

$objConnection = New-Object -com "ADODB.Connection"

$objRecordSet = New-Object -com "ADODB.Recordset"

Tak dla jasności, obiekt Connection zarządza połączeniem z plikiem bazy danych (w tym wypadku C:\Scripts\Test.mdb). Po połączeniu się, obiekt Recordset używany jest do pracy z zestawem rekordów w naszej bazie danych; jeżeli chodzi o dzisiejszy skrypt, to będą to rekordy zawarte w tabeli Computers.

Teraz za pomocą poniższego kodu łączymy się z Test.mdb:

$objConnection.Open("Provider = Microsoft.Jet.OLEDB.4.0; Data Source = C:\Scripts\Test.mdb")

To pierwsza podpucha. Powyższe polecenie łączy nas z Test.mdb, ale niestety tylko wtedy, gdy Test.mdb jest bazą danych programu Access wersji 2003 (lub Access XP). Jeżeli Test.mdb jest na przykład bazą danych programu Access 2007, to powyższy kod możemy wyrzucić do kosza. Dlaczego? Program Access 2007 używa innego ciągu dostawcy oraz innego rozszerzenia pliku. Jak pokonać ten problem? Nie, nie zmieniamy oprogramowania, korzystamy po prostu z trochę innego wiersza kodu:

$objConnection.Open("Provider = Microsoft.ACE.OLEDB.12.0; Data Source = C:\Scripts\Test.accdb")

Nie pytajcie nas, czemu ciąg dostawcy i rozszerzenie zostały zmienione w wersji 2007. Nas tu się nikt nie pyta ani o opinię, ani o zdanie. Ktoś miał po prostu taką fantazję.

Uwaga: Jesteście spostrzegawczy, na pewno zauważyliście więc, że całość informacji dla metody Open podawana jest w nawiasach. To właśnie kolejna pułapka podczas konwertowania skryptu VBScript na Windows PowerShell. W składni Windows PowerShell po wszystkich metodach – a zatem również po metodzie Open – musi następować para nawiasów, wszystkie parametry metody powinny być tam właśnie zawarte. Jeżeli więc umieścicie informację na temat dostawcy w nawiasach w skrypcie VBScript, to nie zadziała; jeśli jednak nie umieścicie tej informacji w nawiasach w skrypcie Windows PowerShell to rezultat będzie taki sam – nie zadziała.

Po połączeniu się z bazą danych używamy poniższego wiersza kodu, który zwraca nam zestaw rekordów z tabeli Computers:

$objRecordset.Open("Select * From Computers", $objConnection,$adOpenStatic,$adLockOptimistic)

Teraz jesteśmy już gotowi, żeby dodać rekord do naszej bazy danych; do tego służy nam poniższy fragment kodu:

$objRecordSet.AddNew()

$objRecordSet.Fields.Item("ComputerName").Value = "atl-ws-001"

$objRecordSet.Fields.Item("SerialNumber").Value = "192ATG43R"

$objRecordSet.Update()

O co chodzi? Już wyjaśniamy nowicjuszom – metoda AddNew tworzy nam nowy, pusty rekord (zwróćcie uwagę na nawias). Następnie przenosimy się do następującego wiersza kodu:

$objRecordSet.Fields.Item("ComputerName").Value = "atl-ws-001"

Mamy wrażenie, AB, że to właśnie ten wiersz nastręczył Ci najwięcej problemów. Nadajemy tu wartość (atl-ws-001) polu ComputerName. Nie jest to może najbardziej skomplikowany wiersz, ale jest to odpowiednik Windows PowerShell kodu VBScript, który w tym samym poleceniu wygląda następująco:

objRecordSet("ComputerName") = "atl-ws-001"

Różnica jest taka, że w skryptach VBScript musimy określić jedynie nawiązanie do obiektu (objRecordset), a następnie dodać nawias zawierający nazwę (ComputerName). W skryptach Windows PowerShell takie uproszczone polecenie nie zadziała, możemy jedynie uzyskać komunikat o błędzie:

Unexpected token '(' in expression or statement.

At C:\scripts\test.ps1:11 char:15

+ $objRecordSet(" 

<<<< ComputerName") = "atl-ws-001"

Tak w sumie to nie wiemy, skąd bierze się ten problem. Jeżeli w VBScript nie określicie dokładnie wszystkich parametrów, to program przydziela im automatycznie parametr domyślny. Dzieje się tak jednak, niestety, w niewielu innych językach – większość z nich wymaga od nas dokładnego sprecyzowania parametrów czy to domyślnych, czy nie. Tak właśnie dzieje się w Windows PowerShell, nic na to nie poradzimy. Domyślamy się, że właściwością domyślną naszego zestawu rekordów jest Fields.Item.(Field name).Value; dlatego też podczas gdy w skrypcie VBScript można podać jedynie nazwę pola i skrypt zadziała, w języku PowerShell musimy podać całą nazwę danej właściwości.

Trzeba trochę zmienić tok myślenia, to prawda. Jak w naszym nowym toku myślenia nadać wartość polu SerialNumber? Właśnie tak:

$objRecordSet.Fields.Item("SerialNumber").Value = "192ATG43R"

Teraz możemy nadawać właściwości tylu polom, ilu nam się żywnie podoba (oczywiście w ramach tabeli Computers). Gdy mamy już tę przyjemną część za sobą, wywołujemy metodę Update i zapisujemy nowy rekord w bazie danych:

$objRecordSet.Update()

Musimy już tylko zamknąć obiekty Connection oraz Recordset i powrócić do hucznych obchodów Dnia Skrypciarza…

Pamiętajcie i zapiszcie do kalendarza: 11.01 DZIEŃ SKRYPCIARZA!

My wracamy do zabawy, bo od jutra znowu raczej Dzień Świstaka („Cześć, Skrypciarze, czy wiecie może jak…?).

 Do początku strony Do początku strony

Centrum Skryptów -Systemy Operacyjne