Apakah ada cara untuk mengeksekusi permintaan arbitrer pada SQL Server menggunakan Powershell di mesin lokal saya?
Apakah ada cara untuk mengeksekusi permintaan arbitrer pada SQL Server menggunakan Powershell di mesin lokal saya?
Jawaban:
Bagi yang lain yang perlu melakukan ini hanya dengan stok .net dan PowerShell (tidak ada alat SQL tambahan yang diinstal) di sini adalah fungsi yang saya gunakan:
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
}
Saya telah menggunakan ini begitu lama saya tidak tahu siapa yang menulis bagian mana tetapi ini disaring dari contoh lain tetapi disederhanakan menjadi jelas dan hanya apa yang dibutuhkan tanpa ketergantungan atau fitur tambahan.
Saya menggunakan dan membagikan ini cukup sering sehingga saya telah mengubah ini menjadi modul skrip di GitHub sehingga Anda sekarang dapat pergi ke direktori modul Anda dan menjalankan git clone https://github.com/ChrisMagnuson/InvokeSQL
dan mulai saat itu invoke-sql akan secara otomatis dimuat ketika Anda menggunakannya (dengan asumsi Anda menggunakan PowerShell v3 atau yang lebih baru).
$connection.dispose()
dll. Saya tidak tahu apakah itu ada bedanya
Anda dapat menggunakan Invoke-Sqlcmd
cmdlet
Invoke-Sqlcmd -Query "SELECT GETDATE() AS TimeOfQuery;" -ServerInstance "MyComputer\MyInstance"
Import-Module "sqlps" -DisableNameChecking
Inilah contoh yang saya temukan di blog ini .
$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();
Agaknya Anda bisa mengganti pernyataan TSQL yang berbeda di mana katanya dbcc freeproccache
.
ExecuteNonQuery()
kembali nol pada keberhasilan, kondisi yang saya gunakan adalah: if ($cmd.ExecuteNonQuery() -ne 0)
.
Fungsi ini akan mengembalikan hasil kueri sebagai array objek PowerShell sehingga Anda dapat menggunakannya dalam filter dan mengakses kolom dengan mudah:
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
(lihat jawaban Adam )?
Jika Anda ingin melakukannya di mesin lokal Anda daripada dalam konteks SQL server maka saya akan menggunakan yang berikut ini. Itu yang kami gunakan di perusahaan saya.
$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
Cukup isi $ ServerName , $ DatabaseName dan $ Query variabel dan Anda harus melakukannya dengan baik.
Saya tidak yakin bagaimana kami menemukan ini pada awalnya, tetapi ada sesuatu yang sangat mirip di sini .
Tidak ada cara "PowerShell" bawaan untuk menjalankan kueri SQL. Jika Anda memiliki alat SQL Server diinstal , Anda akan mendapatkan cmdlet Invoke-SqlCmd .
Karena PowerShell dibangun di atas .NET, Anda dapat menggunakan API ADO.NET untuk menjalankan kueri Anda.
Untuk menghindari SQL Injection dengan parameter varchar yang bisa Anda gunakan
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