Có cách nào để thực hiện một truy vấn tùy ý trên Máy chủ SQL bằng Powershell trên máy cục bộ của tôi không?
Có cách nào để thực hiện một truy vấn tùy ý trên Máy chủ SQL bằng Powershell trên máy cục bộ của tôi không?
Câu trả lời:
Đối với những người khác cần làm điều này chỉ với stock .net và PowerShell (không có công cụ SQL bổ sung nào được cài đặt) ở đây là chức năng mà tôi sử dụng:
function Invoke-SQL {
param(
[string] $dataSource = ".\SQLEXPRESS",
[string] $database = "MasterData",
[string] $sqlCommand = $(throw "Please specify a query.")
)
$connectionString = "Data Source=$dataSource; " +
"Integrated Security=SSPI; " +
"Initial Catalog=$database"
$connection = new-object system.data.SqlClient.SQLConnection($connectionString)
$command = new-object system.data.sqlclient.sqlcommand($sqlCommand,$connection)
$connection.Open()
$adapter = New-Object System.Data.sqlclient.sqlDataAdapter $command
$dataset = New-Object System.Data.DataSet
$adapter.Fill($dataSet) | Out-Null
$connection.Close()
$dataSet.Tables
}
Tôi đã sử dụng nó rất lâu Tôi không biết ai đã viết phần nào nhưng phần này được chắt lọc từ các ví dụ khác nhưng được đơn giản hóa để rõ ràng và chỉ những gì cần thiết mà không cần phụ thuộc hoặc tính năng bổ sung.
Tôi sử dụng và chia sẻ điều này thường xuyên đến mức tôi đã biến nó thành một mô-đun kịch bản trên GitHub để bây giờ bạn có thể đi đến thư mục mô-đun của mình và thực thi git clone https://github.com/ChrisMagnuson/InvokeSQL
và từ đó, invoke-sql sẽ tự động được tải khi bạn sử dụng nó (giả sử sử dụng powershell v3 trở lên).
$connection.dispose()
vv Tôi không biết liệu nó có làm nên sự khác biệt nào không
Bạn có thể sử dụng Invoke-Sqlcmd
lệnh ghép ngắn
Invoke-Sqlcmd -Query "SELECT GETDATE() AS TimeOfQuery;" -ServerInstance "MyComputer\MyInstance"
http://technet.microsoft.com/en-us/l Library / cc281720.aspx
Import-Module "sqlps" -DisableNameChecking
Đây là một ví dụ tôi tìm thấy trên blog này .
$cn2 = new-object system.data.SqlClient.SQLConnection("Data Source=machine1;Integrated Security=SSPI;Initial Catalog=master");
$cmd = new-object system.data.sqlclient.sqlcommand("dbcc freeproccache", $cn2);
$cn2.Open();
if ($cmd.ExecuteNonQuery() -ne -1)
{
echo "Failed";
}
$cn2.Close();
Có lẽ bạn có thể thay thế một tuyên bố TSQL khác trong đó nói dbcc freeproccache
.
ExecuteNonQuery()
không trả về thành công, điều kiện tôi sử dụng là : if ($cmd.ExecuteNonQuery() -ne 0)
.
Hàm này sẽ trả về kết quả của một truy vấn dưới dạng một mảng các đối tượng powershell để bạn có thể sử dụng chúng trong các bộ lọc và truy cập các cột một cách dễ dàng:
function sql($sqlText, $database = "master", $server = ".")
{
$connection = new-object System.Data.SqlClient.SQLConnection("Data Source=$server;Integrated Security=SSPI;Initial Catalog=$database");
$cmd = new-object System.Data.SqlClient.SqlCommand($sqlText, $connection);
$connection.Open();
$reader = $cmd.ExecuteReader()
$results = @()
while ($reader.Read())
{
$row = @{}
for ($i = 0; $i -lt $reader.FieldCount; $i++)
{
$row[$reader.GetName($i)] = $reader.GetValue($i)
}
$results += new-object psobject -property $row
}
$connection.Close();
$results
}
DataTable
(xem câu trả lời của Adam )?
Nếu bạn muốn làm điều đó trên máy cục bộ của bạn thay vì trong ngữ cảnh của máy chủ SQL thì tôi sẽ sử dụng như sau. Đó là những gì chúng tôi sử dụng tại công ty của tôi.
$ServerName = "_ServerName_"
$DatabaseName = "_DatabaseName_"
$Query = "SELECT * FROM Table WHERE Column = ''"
#Timeout parameters
$QueryTimeout = 120
$ConnectionTimeout = 30
#Action of connecting to the Database and executing the query and returning results if there were any.
$conn=New-Object System.Data.SqlClient.SQLConnection
$ConnectionString = "Server={0};Database={1};Integrated Security=True;Connect Timeout={2}" -f $ServerName,$DatabaseName,$ConnectionTimeout
$conn.ConnectionString=$ConnectionString
$conn.Open()
$cmd=New-Object system.Data.SqlClient.SqlCommand($Query,$conn)
$cmd.CommandTimeout=$QueryTimeout
$ds=New-Object system.Data.DataSet
$da=New-Object system.Data.SqlClient.SqlDataAdapter($cmd)
[void]$da.fill($ds)
$conn.Close()
$ds.Tables
Chỉ cần điền vào các biến $ ServerName , $ DatabaseName và $ Query và bạn sẽ thấy ổn.
Tôi không chắc làm thế nào ban đầu chúng tôi phát hiện ra điều này, nhưng có một cái gì đó rất giống ở đây .
Không có cách "PowerShell" tích hợp để chạy truy vấn SQL. Nếu bạn đã cài đặt các công cụ SQL Server , bạn sẽ nhận được lệnh ghép ngắn Invoke-SqlCmd .
Vì PowerShell được xây dựng trên .NET, bạn có thể sử dụng API ADO.NET để chạy các truy vấn của mình.
Để tránh SQL Injection với các tham số varchar bạn có thể sử dụng
function sqlExecuteRead($connectionString, $sqlCommand, $pars) {
$connection = new-object system.data.SqlClient.SQLConnection($connectionString)
$connection.Open()
$command = new-object system.data.sqlclient.sqlcommand($sqlCommand, $connection)
if ($pars -and $pars.Keys) {
foreach($key in $pars.keys) {
# avoid injection in varchar parameters
$par = $command.Parameters.Add("@$key", [system.data.SqlDbType]::VarChar, 512);
$par.Value = $pars[$key];
}
}
$adapter = New-Object System.Data.sqlclient.sqlDataAdapter $command
$dataset = New-Object System.Data.DataSet
$adapter.Fill($dataset) | Out-Null
$connection.Close()
return $dataset.tables[0].rows
}
$connectionString = "..."
$sql = "select top 10 Message, TimeStamp, Level from dbo.log "+
"where Message = @MSG and Level like @LEVEL ";
$pars = @{
MSG = 'this is a test from powershell';
LEVEL = 'aaa%';
};
sqlExecuteRead $connectionString $sql $pars