Вы можете сделать SQL в PowerShell просто, заменив строку, например, «параметры», которые вы можете передать Invoke-Sqlcmd
.Я советую вам этого не делать: он оставляет вас открытым для инъекций, и вы должны быть особенно внимательны при форматировании дат, NULL
значений, значений с плавающей точкой, строк ... Вот две функции, которые помогут вам сделать это способом .NET:
function ConvertFrom-DataReader($datareader) {
$values = New-Object Object[] $datareader.FieldCount
$names = New-Object string[] $datareader.FieldCount
$anyNameEmpty = $false
for ($i = 0; $i -lt $values.Length; $i++) {
$names[$i] = $datareader.GetName($i)
if (-not $names[$i]) { $anyNameEmpty = $true }
}
while ($datareader.Read()) {
$v = $datareader.GetValues($values)
if ($anyNameEmpty) {
Write-Output $values
} else {
$result = New-Object psobject
for ($i = 0; $i -lt $v; $i++) {
Add-Member `
-InputObject $result `
-MemberType NoteProperty `
-Name $names[$i] `
-Value $values[$i]
}
Write-Output $result
}
}
}
function Invoke-SqlCommand(
[string] $ConnectionString,
[string] $CommandText,
[hashtable] $Parameters = @{}
) {
$connection = New-Object System.Data.SqlClient.SqlConnection($ConnectionString)
try {
$connection.Open()
$command = New-Object System.Data.SqlClient.SqlCommand
$command.Connection = $connection
$command.CommandText = $commandText
$command.CommandType = [System.Data.CommandType]::Text
foreach ($Name in $Parameters.Keys) {
$command.Parameters.AddWithValue($Name, $Parameters[$Name]) | Out-Null
}
ConvertFrom-DataReader $command.ExecuteReader()
} finally {
$connection.Close()
}
}
Пример использования:
Invoke-SqlCommand `
-ConnectionString "Data Source=(localdb)\mssqllocaldb" `
-CommandText "DECLARE @myTable TABLE(name VARCHAR(100), dateChanged DATETIME);
INSERT INTO @myTable (name, dateChanged) VALUES (@name, @dateChanged);
SELECT * FROM @myTable" `
-Parameters @{
name = "Winston"
dateChanged = Get-Date
}
Это не идеально (вы могли бы использовать надлежащие командлеты, AddWithValue
имеет проблемы ), и вы могли бы рассмотреть этоперебор для одноразового запроса, но это все же гораздо лучше, чем текстовая замена.