Поиск на сайте: Расширенный поиск


Новые программы oszone.net Читать ленту новостей RSS
CheckBootSpeed - это диагностический пакет на основе скриптов PowerShell, создающий отчет о скорости загрузки Windows 7 ...
Вы когда-нибудь хотели создать установочный диск Windows, который бы автоматически установил систему, не задавая вопросо...
Если после установки Windows XP у вас перестала загружаться Windows Vista или Windows 7, вам необходимо восстановить заг...
Программа подготовки документов и ведения учетных и отчетных данных по командировкам. Используются формы, утвержденные п...
Red Button – это мощная утилита для оптимизации и очистки всех актуальных клиентских версий операционной системы Windows...
OSzone.net Microsoft PowerShell Windows PowerShell: Доступ к базам данных из PowerShell RSS

Windows PowerShell: Доступ к базам данных из PowerShell

Текущий рейтинг: 5 (проголосовало 2)
 Посетителей: 4275 | Просмотров: 5748 (сегодня 0)  Шрифт: - +

Мне очень часто задавали вопрос, как заставить Windows PowerShell использовать данные из базы данных, например в SQL Server. Это стало происходить так часто, что я решил посвятить этому главу в своей электронной книге «Windows PowerShell Scripting and Toolmaking» (lulu.com, 2011).

Мое решение заключается в создании двух функций: одна запрашивает данные, а другая меняет их (то есть выполняет вставку, удаление и обновление). В этому случае функциональность оказывается самодостаточной и ее можно повторно использовать во многих проектах. Так как возможности доступа к базам данных встроены в Microsoft .NET Framework, не нужно ничего дополнительно устанавливать, кроме Windows PowerShell.

Функции для работы с базами данных

Чтобы было легче работать с этими функциями, сохраните их в модуле. Например, я свои поместил в файл \MyDocuments\WindowsPowerShell\Modules\DataTools\DataTools.psm1. Вот код модуля:

function Get-DatabaseData {
	[CmdletBinding()]
	param (
		[string]$connectionString,
		[string]$query,
		[switch]$isSQLServer
	)
	if ($isSQLServer) {
		Write-Verbose 'in SQL Server mode'
		$connection = New-Object-TypeName System.Data.SqlClient.SqlConnection
	} else {
		Write-Verbose 'in OleDB mode'
		$connection = New-Object-TypeName System.Data.OleDb.OleDbConnection
	}
	$connection.ConnectionString = $connectionString
	$command = $connection.CreateCommand()
	$command.CommandText = $query
	if ($isSQLServer) {
		$adapter = New-Object-TypeName System.Data.SqlClient.SqlDataAdapter $command
	} else {
		$adapter = New-Object-TypeName System.Data.OleDb.OleDbDataAdapter $command
	}
	$dataset = New-Object-TypeName System.Data.DataSet
	$adapter.Fill($dataset)
	$dataset.Tables[0]
}
function Invoke-DatabaseQuery {
	[CmdletBinding()]
	param (
		[string]$connectionString,
		[string]$query,
		[switch]$isSQLServer
	)
	if ($isSQLServer) {
		Write-Verbose 'in SQL Server mode'
		$connection = New-Object-TypeName System.Data.SqlClient.SqlConnection
	} else {
		Write-Verbose 'in OleDB mode'
		$connection = New-Object-TypeName System.Data.OleDb.OleDbConnection
	}
	$connection.ConnectionString = $connectionString
	$command = $connection.CreateCommand()
	$command.CommandText = $query
	$connection.Open()
	$command.ExecuteNonQuery()
	$connection.close()
}

Ничего не перепутайте и сохраните свой модуль в ветке со своими пользовательскими документами (My Documents), а не с общими документами (Shared Documents). В этом случае Windows PowerShell сможет корректно их найти. Затем для загрузки файла просто выполните команду Import-Module DataTools.

Чтобы воспользоваться этим, можно вызвать команду Get-DatabaseData или Invoke-DatabaseQuery. У этих команд есть параметр –isSQLServer, который надо использовать при запросе SQL Server, иначе Windows PowerShell посчитает, что вы обращаетесь к OleDB-источнику, который не является SQL Server. Нужно также предоставить параметры –connectionString и –query.

Например, чтобы удалить все данные в таблице по имени MyTable в базе данных MyDatabase на машине с SQL Server по имени Server1, на которой установлен именованный экземпляр SQL Server SQLEXPRESS, надо выполнить следующую команду (заметьте, что я предоставляю имя входа и пароль в стиле SQL Server, а не имя входа с использованием интегрированной проверки подлинности):

Invoke-DatabaseQuery –query "DELETE FROM MyTable" –isSQLServer –connectionString "Data Source=SERVER1\SQLEXPRESS;Initial Catalog=MyDatabase;User Id=myLogin;Password=P@ssw0rd"

Небольшое уточнение: я не помню синтаксис строки подключения. И не сильно стараюсь ее запомнить. Я просто иду на сайт connectionstrings.com и нахожу там нужный мне пример.

Команда Invoke-DatabaseQuery не возвращает никакой информации, что нельзя сказать о команде Get-DatabaseData. В частности, она возвращает DataTable, которая представляет собой коллекцию объектов, каждый из которых является строкой результатов запроса. Свойства каждого объекта соответствуют столбцам результата запроса.

Тестирование и еще раз тестирование

Давайте выполним полный цикл тестирования. Воспользуйтесь бесплатной редакцией SQL Server Express Edition, которая устанавливается как именованный экземпляр SQLEXPRESS. Я загрузил и установил версию, в которую входит средство Express Management Studio. Все это я выполнил на своем компьютере. В этом примере я буду полагаться на проверку подлинности Windows, а не SQL Server.

Я открыл консоль SQL Server Management Studio и подключился к экземпляру localhost\SQLEXPRESS (я вошел в систему как Administrator и просто использовал эти учетные данные для доступа к серверу баз данных). Я открыл новое окно запроса и выполнил следующий запрос создания примера базы данных:

CREATE DATABASE [Inventory] ON  PRIMARY
( NAME = N'Inventory', FILENAME = N'c:\Program Files\Microsoft SQL Server\MSSQL10_50.SQLEXPRESS\MSSQL\DATA\Inventory.mdf' , SIZE = 2048KB , FILEGROWTH = 1024KB )
 LOG ON
( NAME = N'Inventory_log', FILENAME = N'c:\Program Files\Microsoft SQL Server\MSSQL10_50.SQLEXPRESS\MSSQL\DATA\Inventory_log.ldf' , SIZE = 1024KB , FILEGROWTH = 10%)
GO
USE [Inventory]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Computers](
[computer] [nvarchar](50) NULL,
[osversion] [nvarchar](100) NULL,
[biosserial] [nvarchar](100) NULL,
[osarchitecture] [nvarchar](5) NULL,
[procarchitecture] [nvarchar](5) NULL
) ON [PRIMARY]

GO

Затем я удалил предыдущий запрос из окна и выполнил следующий запрос:

Use [Inventory]
Go
INSERT INTO Computers (computer) VALUES ('localhost')
INSERT INTO Computers (computer) VALUES ('localhost')
INSERT INTO Computers (computer) VALUES ('not-online')

Этот запрос добавляет в таблицу три строки данных. Затем я переключился в Windows PowerShell. После импорта своего модуля DataTools я выполнил следующие команды:

Get-DatabaseData -verbose -connectionString 'Server=localhost\SQLEXPRESS;Database=Inventory;Trusted_Connection=True;' -isSQLServer-query "SELECT * FROM Computers"
Invoke-DatabaseQuery -verbose -connectionString 'Server=localhost\SQLEXPRESS;Database=Inventory;Trusted_Connection=True;' -isSQLServer-query "INSERT INTO Computers (computer) VALUES('win7')"
Get-DatabaseData -verbose -connectionString 'Server=localhost\SQLEXPRESS;Database=Inventory;Trusted_Connection=True;' -isSQLServer-query "SELECT * FROM Computers"

Это подтверждает, что я сначала добавил три записи, после чего добавил еще одну.

Базы данных без проблем

Использование этих двух функций экономит мне много времени. Каждый раз, когда мне нужно что-то загрузить или записать в базу данных, я просто импортирую свой модуль и все.

Не обязательно хранить в указанной мной папке. Его можно размещать где угодно, если только вы готовы каждый раз указывать полный путь к psm1-файлу при выполнении команды Import-Module. Однако если модуль находится в указанной папке, его можно импортировать просто по имени, не указывая путь. Это дополнительно экономит время.

Автор: Дон Джонс  •  Иcточник: TechNet Magazine  •  Опубликована: 04.07.2012
Нашли ошибку в тексте? Сообщите о ней автору: выделите мышкой и нажмите CTRL + ENTER
Теги:   Powershell.


Оценить статью:
Вверх
Комментарии посетителей
Комментарии отключены. С вопросами по статьям обращайтесь в форум.