invoke-sqlcmd失败,对某些类型的查询不显示任何结果

时间:2018-10-21 09:36:13

标签: sql-server powershell

Invoke-Sqlcmd -ServerInstance '.' -Database 'MyDB' 
      -Query 'EXEC SprocA  @param1= "value";EXEC SprocB  @param1= "value";'

基本上,我的Invoke-SqlCmd运行着一个查询,该查询调用了两个存储过程。这两个存储过程都输出一堆行。

但是,如果sprocA没有输出任何结果(空选择结果或没有行),则invoke命令似乎没有打印第二个sprocB的输出,即使它具有数据。

如果我在Invoke-SqlCmd命令的查询参数中更改了存储过程的顺序,那么它可以完美工作并返回第一个存储过程的输出。

如果我有三个存储过程调用,其中第一个返回数据,第二个不返回数据,而第三个则返回,它将打印第一个结果和第三个结果的输出。

基本上,仅当第一个存储过程没有输出时,它才不输出任何输出。看起来很奇怪。

我能做些什么来解决这个SQL问题?可能是PowerShell的东西吗?

我还可以通过两条Select语句来对此进行复制,其中一条返回数据而另一条不返回数据。

2 个答案:

答案 0 :(得分:2)

这是invoke-sqlcmd

的已记录行为
  

运行此cmdlet时,脚本返回的第一个结果集   显示为格式化表格。如果后续结果集包含   与第一个不同的列列表,这些结果集不是   显示。如果第一组之后的后续结果集相同   列列表,它们的行将追加到   包含第一个结果集返回的行。

看起来两个结果集实际上都已返回,但defaut并未输出。

EG

   PS C:\> Invoke-SqlCmd "select 1 a; select 2 b, 3 c;" | % { $_ | Out-Default }

输出

a
-
1



b c
- -
2 3

答案 1 :(得分:0)

实际上,很难相信MS犯了这样的错误,或者也许这不是错误。无论如何,当您运行Invoke-SqlCmd并使用如下查询时,

select * from table1 where id = 1111 -- non-exists id, this select returns nothing
select * from table2 where id = 2222 -- exists id, this select returns something

在SSMS上,您可以看到2个结果集,第一个是空的。

但是,当第一个结果集为空时,Invoke-SqlCmd不会返回任何内容,即使其他结果集也不为空。我的脸像?_?

另一种方法是编写自己的调用SQL函数,如下面的示例,以返回任何结果集,甚至是空结果集。

    $sql_Conn = New-Object System.Data.SqlClient.SQLConnection
    $sql_Conn.ConnectionString = $sqlConnectionString
    $sql_Conn.Open()
    $sql_cmd = New-Object system.Data.SqlClient.SqlCommand($Query, $sql_Conn)
    $sql_ds = New-Object system.Data.DataSet
    $sql_da = New-Object system.Data.SqlClient.SqlDataAdapter($sql_cmd)
    [void]$sql_da.fill($sql_ds)
    $sql_Conn.Close()
    return $sql_ds

一切正常,直到脚本中的关键字GO出现新问题为止,如果您使用SSMS,则必须知道它。问题是,此GO不是SQL命令。它只是SSMS使用的分隔符。 MS开发的代码可以很好地处理GO,例如SSMS Invoke-SqlCmdsqlcmd.exe。如果使用自己的SQL调用函数,则会出现语法问题

Incorrect syntax near 'GO'

虽然人们最有可能要求您更新SQL脚本以删除所有GO行,但是,事情并不总是处于受控状态,通常需要与不同的人和团队合作。

最后,我必须像下面这样修剪脚本中的GO

$Query = $Query -ireplace "(^|\r|\n)[ \t]*\bGO\b[ \t]*(\r|\n|$)", '$1$2'

https://github.com/LarrysGIT/Invoke-Sql

当然,故事还没有结束,我尝试使SQL相关任务自动化的程度更高。找到更多问题。有多种方法可以自动执行SQL脚本。到目前为止,没有一个是完美的。

Invoke-Sql(我自己的脚本)

* Is able to handle the key separator 'GO'
* Is able to handle duplicate columns
* Fully support multiple result sets, even the first result set is empty
* Unable to handle `Create or alter` keywords if there are contents ahead
* Unable to handle special characters like '194 160' (non-breaking space) in SQL script (edited by some document edit tool, MS word for example)

Invoke-SqlCmd

* Is able to handle the key separator 'GO'
* Is able to handle special characters like 'non-breaking space'
* Unable to handle duplicate columns
* Unable to fully handle multiple result sets (when the first table is empty)

sqlcmd.exe

* Is able to handle all things (briefly tested)
* The returned result sets are plain text, hard to parse

Microsoft.SqlServer.SMO管理单元

* The API of SQL server management studio
* Theoretically should be able to handle all cases
* Need to dig more