如何从PowerShell执行sqlcmd命令?

22

我在 PowerShell 中有一个字符串,其中包含本地 sqlcmd 命令。该命令在 cmd.exe 中本身可以成功执行,但我在 PowerShell 中无法执行它。 有人能帮忙吗?谢谢。

这是 sql.sql

select @@servername
go
select @@servicename

当我从cmd.exe执行sqlcmd命令时,这就是结果。

C:\Users\test>sqlcmd -S "(local)\instance1" -U a -P a -i "c:\temp\sql.sql"

--------------------------------------------------
thesimpsons\INSTANCE1

(1 rows affected)

--------------------------------------------------
INSTANCE1

(1 rows affected)

C:\Users\test>

这是调用sqlcmd命令的PowerShell脚本。

$sql = @"
sqlcmd -S "(local)\instance1" -U a -P a -i "c:\temp\sql.sql"
"@

Invoke-Command $sql
当我执行这个 PowerShell 脚本时,我得到了以下错误。
PS C:\TEMP> $sql = @"
sqlcmd -S "(local)\instance1" -U a -P a -i "c:\temp\sql.sql"
"@

Invoke-Command $sql
Invoke-Command : Parameter set cannot be resolved using the specified named parame
ters.
At line:5 char:15
+ Invoke-Command <<<<  $sql
    + CategoryInfo          : InvalidArgument: (:) [Invoke-Command], ParameterBin 
   dingException
    + FullyQualifiedErrorId : AmbiguousParameterSet,Microsoft.PowerShell.Commands 
   .InvokeCommandCommand

相关:http://stackoverflow.com/questions/1015038/powershell-sqlcmd - Ruben Bartelink
7个回答

26
要调用一个Win32可执行文件,你需要使用调用运算符&,如下所示:
& sqlcmd -S "(local)\instance1" -U a -P a -i "c:\temp\sql.sql"

20

您还可以停止使用外部的 'SQLCMD.EXE',改用Invoke-Sqlcmd cmdlet:

Invoke-Sqlcmd是一个SQL Server cmdlet,可运行包含Transact-SQL和XQuery语言支持的语句和命令的脚本,与sqlcmd实用程序相同。

只需打开 'sqlps' 实用程序并运行即可。

Invoke-Sqlcmd -InputFile "C:\temp\sql.sql"
请参见运行 SQL Server PowerShell
您还可以在使用“Invoke-Sqlcmd”之前在 PowerShell 中手动加载 SQL Server 的快照;
对于 MS SQL Server 2012,您可以通过运行
Import-Module SqlPs来实现。

1
虽然Andi Arismendi的回答很好,直接回答了sqlcmd可执行文件的执行问题,但我认为这个应该是被采纳的答案。如果你通过powershell运行sqlcmd脚本,使用Invoke-Sqlcmd将节省你的时间、精力和按键次数。 - ascary
7
  1. Invoke-Sqlcmd不能执行所有可用于SQLCMD的命令。
  2. 在基本的Powershell安装中没有包含Invoke-Sqlcmd。
- DonBecker
Invoke-Sqlcmd会在存储过程的末尾添加一个分号,这会导致比较工具出现问题。请参见https://social.msdn.microsoft.com/Forums/sqlserver/en-US/74d8acd4-9788-48e5-93bc-fa165a573ee2/powershell-invokesqlcmd-adding-semicolon?forum=sqltools和https://www.reddit.com/r/PowerShell/comments/5v29o2/options_for_executing_sql_server_script/。 - kevinpo
更不用说,在Powershell 2.0中不支持Invoke-Sqlcmd。 - tbradt

6
这是我在脚本中构建一些外部命令的方法。
$scriptblock = {fullpath\sqlcmd -S `"(local)\instance1`" <# comment option -S #>`
                                -U a `
                                -P a `
                                -i `"c:\temp\sql.sql`" }
Invoke-Command -ScriptBlock $scriptBlock

您可以在其中使用$args变量,甚至可以远程启动它。
$scriptblock = {fullpath\sqlcmd -S `"(local)\instance1`" <# comment option -S #>`
                                -U a `
                                -P a `
                                -i `"$($args[0])`" }
Invoke-Command -ScriptBlock $scriptBlock -argumentList "c:\temp\sql.sql" -computer "remote1"

备注:

这允许对每个参数进行注释。

注意,在行尾处的 "`" 后面不要加空格,也不要忘记它们。


3

invoke-command 的第一个位置参数是 -scriptblock,需要传入一个脚本块参数。如果要利用 here-string 构建命令,并使用 invoke-command 运行它,则需要将 here-string 转换为脚本块:

$sql = @"
sqlcmd -S "(local)\instance1" -U a -P a -i "c:\temp\sql.sql"
 "@

 Invoke-Command ([scriptblock]::create($sql))

所有这个程序将要做的事情就是返回$sql中的值,它实际上并不会执行它(至少不在我的机器上)。 - user847990

3
使用Invoke-Expression替代Invoke-Command

我不明白为什么人们在调用Win32可执行文件时要尝试使用Invoke-Expression...这就是调用运算符的作用。 - Andy Arismendi
@Andy - Invoke-Expression允许您首先将整个命令生成为一个字符串,这在特定情况下可能会很有用。请参考https://dev59.com/72w15IYBdhLWcg3wcrZC - Andrew Shepherd
1
是的,但这里不需要。只有在需要评估表达式时才使用Invoke-Expression。 - Andy Arismendi

0

实例名称和用户名都应该是完全限定的

<domain_name>\Instanc_name<domai_name>\Username,只有你的实例名称被正确编写。


0

这是我在使用 & 运算符从 powershell 脚本中使用 sqlcmd 时所使用的方法,可以参考下面的示例生成 csv 文件:

& cmd /c "sqlcmd -S $sv -i $PROCFILE -s, -v varDB = $dbclean -o $filename"

$sv 是服务器名称,如 SERVERNAME\INSTANCE

$PROCFILE 类似于 d:\TSTSQL\Sqlquery.SQL

$filenamed:\TSTSQL\Desiredoutfilename.CSV

$dbclean 是传递给 SQL 文件的参数


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接