动态 SQL Where 条件,在 Powershell 脚本中

Posted

技术标签:

【中文标题】动态 SQL Where 条件,在 Powershell 脚本中【英文标题】:Dynamic SQL Where condition, in Powershell script 【发布时间】:2020-01-18 17:13:22 【问题描述】:

我正在研究一个 Powershell 脚本,其中查询 #1 的输出是查询 #2 的条件提要,但它没有获取提要,如果有人请查看并告诉我可能的解决方案。

另外请注意,在实际环境中,两个查询都在不同的实例上运行,并且没有链接服务器的可能性

下面的例子是我在AdventureWorks 数据库中尝试的:

$instance="WIN2016-SQL01\SQLSERVER_01"
$database = "AdventureWorks2014"
$query1 = "SELECT TOP 10 [BusinessEntityID]   FROM [AdventureWorks2014].[Person].[BusinessEntityAddress] where BusinessEntityID < 10 order by 1 "
$Q1 = (invoke-sqlcmd -query $query1 -ServerInstance $instance -Database $database)

$query2 = "SELECT *   FROM [AdventureWorks2014].[Person].[Person] where BusinessEntityID in ($Q1)"
$Q2 = invoke-sqlcmd -query $query2 -ServerInstance $instance -Database $database 

【问题讨论】:

检查 $query2 值,您会看到 $Q1 值变为“System.Data.DataRow System.Data.DataRow...”。您需要使用不同的技术来提供值列表。将您正在使用的 SQL Server 版本添加到您的问题中,以便您获得最适合您情况的答案。 #SQL Server 版本:2014 # PSVersion:5.1.14393.20 【参考方案1】:

或者您可以构建一个分隔字符串来代替您的 IN 子句:

$instance="localhost"
$database = "AdventureWorks2017"
$query1 = "SELECT TOP 10 [BusinessEntityID] FROM [Person].[BusinessEntityAddress] where BusinessEntityID < 10 order by 1 "
$Q1 = (invoke-sqlcmd -query $query1 -ServerInstance $instance -Database $database)

$ids = ""
foreach ($r in $Q1)

  $ids += ","  + $r.BusinessEntityID


$ids = $ids.Substring(1)

$query2 = "SELECT * FROM [Person].[Person] where BusinessEntityID in ($ids)"
$Q2 = invoke-sqlcmd -query $query2 -ServerInstance $instance -Database $database 

$Q2 | format-table 

【讨论】:

谢谢,简单明了。它奏效了。 或者,更简单:$ids = $Q1.BusinessEntityID -join ','【参考方案2】:

值列表可以作为 XML 参数传递给查询,其中 XML 方法可用于提取值。 JSON 字符串值是 SQL 2016 及更高版本中的一个选项,但我看到您使用的是 SQL Server 2014。

下面的示例将 BusinessEntityID 值的 Q1 结果列表转换为 XML 参数值。由于 Invoke-SqlCmd 不支持参数化查询,因此需要直接使用 SqlClient 对象。 Invoke-SqlCmd 的替代品是来自 dbatools 的 Invoke-DbaQuery,如果您有参数化查询,它支持参数化查询。

$instance="WIN2016-SQL01\SQLSERVER_01"
$database = "AdventureWorks2014"
$query1 = "SELECT TOP 10 [BusinessEntityID]   FROM [AdventureWorks2014].[Person].[BusinessEntityAddress] where BusinessEntityID < 10 order by 1 "
$Q1 = (invoke-sqlcmd -query $query1 -ServerInstance $instance -Database $database)

$list = @()
foreach ($row in $Q1)
   
    $list += $row["BusinessEntityID"]

$listXml = $list | ConvertTo-Xml -NoTypeInformation
$listXmlString = $x.Objects.InnerXml

$query2 = "SELECT * 
FROM [AdventureWorks2014].[Person].[Person] 
WHERE BusinessEntityID IN (
    SELECT item.value('.','int')
    FROM @list.nodes('/Object') AS list(item)
    );"

$connectionString = "Data Source=$instance;Initial Catalog=$database;Integrated Security=SSPI"
$connection = New-Object System.Data.SqlClient.SqlConnection($connectionString)
$command = New-Object System.Data.SqlClient.SqlCommand($query2, $connection)
$dataAdapter = New-Object System.Data.SqlClient.SqlDataAdapter($command)
($command.Parameters.Add("@list", [System.Data.SqlDbType]::Xml)).Value = $listXmlString
$Q2 = New-Object System.Data.DataTable
$dataAdapter.Fill($Q2)

【讨论】:

以上是关于动态 SQL Where 条件,在 Powershell 脚本中的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL 执行多个动态 WHERE 条件而不动态编写 SQL

动态SQL之<where;<if;条件判断

准备好的语句中的动态 where 条件的 SQL 注入

oracle sql中where条件的动态数量

如何针对 JSON 列构建动态 SQL where 条件

三:动态SQL