如何使用PowerShell和SQLCMD获取存储过程返回值?

时间:2018-04-21 10:20:38

标签: sql-server powershell

我有一个SQL Server存储过程,它返回一个结果集和一个整数返回值。我想使用SQLCMD执行它,PowerShell将结果集重定向到文本文件并捕获PowerShell变量中的返回值。

我的问题是,我无法将返回值捕获到$ RC变量中。

存储过程:

CREATE PROCEDURE [DBO].[TEST]
AS
BEGIN
  SET NOCOUNT ON;

  DECLARE @MYTABLE TABLE(PARTNO INT, TRANDATE DATE, QUANTITY INT)

  INSERT INTO @MYTABLE 
  VALUES (1, '2018-01-01', 1000), (1, '2018-02-01', 2000),
         (2, '2018-03-01', 3000)

  SELECT * 
  FROM @MYTABLE 

  RETURN @@ROWCOUNT
END

Powershell脚本类似于:

Param();
Clear-Host; 

$Command = "Exec [test].[dbo].[Test]";
$RC = sqlcmd -Q $Command -s ',' -u -h-1 -W | Out-File "C:\Test.txt";
Write-Host $RC;

提前致谢。

1 个答案:

答案 0 :(得分:1)

如果语句返回ResultSet,SQLCMD -Q "EXIT(stmt)将省略返回码。 它在代码示例sqlcmd -Q "EXIT(SELECT COUNT(*) FROM '%1')下描述了there 此外,还保留了SQLCMD的一些退出代码。

有一个基于临时文件的解决方法。 你会发现这个拐杖很有用。

# Control
$TMP_FILE = [System.IO.Path]::GetTempFileName() # A return code will be placed in that file.
$PROC_NAME = "testdb.dbo.test"
$SQL_BATCH = "set nocount on;
create table #ret_code_store (ret_code int); -- You have to store @ret_code in that temp table because GO will erase ret_code's variable.
declare @ret_code as int; 
exec @ret_code = $PROC_NAME;
insert into #ret_code_store values(@ret_code);
go -- You need it because it separates STDOUT from ret_code's file.
:Out $TMP_FILE
select ret_code from #ret_code_store;
:EXIT()"

# Do work
$RECORD_SET = (sqlcmd -Q $SQL_BATCH -s ',' -u -h-1 -W) # Returns a ResultSet from SP. You can proceed it as you want.
$RET_CODE = [System.Convert]::toint32((Get-Content $TMP_FILE | Select-Object -Last 1))
Remove-Item -Path $TMP_FILE # There is a limit up to 65535. Lets respect OS limitations.

# Results
Write-Output "Return: $RET_CODE`n"
Write-Output "ResultSet:`n"
Write-Output $RECORD_SET