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

Dynamic SQL Where condition, in Powershell script

我正在处理一个 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 

值列表可以作为 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)

或者您可以构建一个分隔字符串来替代您的 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