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