使用powershell example from msdn docs作为参考,假设我正在与sql server数据库交谈:
$srv = new-Object Microsoft.SqlServer.Management.Smo.Server("(local)")
$db = New-Object Microsoft.SqlServer.Management.Smo.Database
$db = $srv.Databases.Item("AdventureWorks2012")
$db.ExecuteNonQuery("CHECKPOINT")
$ds = $db.ExecuteWithResults("SELECT * FROM Person.Address")
Foreach ($t in $ds.Tables)
{
Foreach ($r in $t.Rows)
{
Foreach ($c in $t.Columns)
{
Write-Host $c.ColumnName "=" $r.Item($c)
}
}
}
如何将变量值注入传递给$db.ExecuteWithResults
的sql中,就像我对sqlcmd一样,如下所示:
sqlcmd -v person="name" -i c:\testscript.sql
示例sql可能如下所示:
declare @PersonsName varchar(100) = '$(person)';
select * from Persons
where name = @PersonsName;
除了在sql本身上做一个令人讨厌的字符串替换之外,我在使用ExecuteWithResults
时看不到包含此类注入的任何选项?
忽略这可能会在这里打开的任何sql注入问题,我不想围绕这个问题讨论安全问题。
答案 0 :(得分:1)
Microsoft.SqlServer.Management.Smo.ExecuteWirthResults method documentation仅显示字符串和字符串集合重载,因此您将无法执行参数化查询。在PowerShell中,您只需在查询文本中指定变量名称,PS将在运行时替换为实际字符串:
$ds = $db.ExecuteWithResults("select * from Persons where name = '$person';")
考虑使用SqlClient而不是SMO来执行查询,以便您可以执行参数化查询:
$connectionString = "Data Source=.;Initial Catalog=AdventureWorks2012;Integrated Security=SSPI"
$connection = New-Object System.Data.SqlClient.SqlConnection($connectionString)
$command = New-Object System.Data.SqlClient.SqlCommand("CHECKPOINT", $connection)
$connection.Open()
[void]$command.ExecuteNonQuery()
$command.CommandText = "SELECT * FROM Person.Person WHERE LastName = @PersonsName;";
$person = "Duffy";
[void](($command.Parameters.Add("@PersonsName", [System.Data.SqlDbType]::NVarChar, 100)).Value = $person);
$dt = New-Object System.Data.DataTable
$da = New-Object System.Data.SqlClient.SqlDataAdapter($command)
[void]$da.Fill($dt)
$dt | Format-Table