[英]How do I call a SQL Server stored procedure from PowerShell?
I have a large CSV file and I want to execute a stored procedure for each line.我有一个大的 CSV 文件,我想为每一行执行一个存储过程。
What is the best way to execute a stored procedure from PowerShell?从 PowerShell 执行存储过程的最佳方法是什么?
This answer was pulled from http://www.databasejournal.com/features/mssql/article.php/3683181这个答案来自http://www.databasejournal.com/features/mssql/article.php/3683181
This same example can be used for any adhoc queries.此相同示例可用于任何即席查询。 Let us execute the stored procedure “sp_helpdb” as shown below.
让我们执行如下所示的存储过程“sp_helpdb”。
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server=HOME\SQLEXPRESS;Database=master;Integrated Security=True"
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = "sp_helpdb"
$SqlCmd.Connection = $SqlConnection
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$DataSet = New-Object System.Data.DataSet
$SqlAdapter.Fill($DataSet)
$SqlConnection.Close()
$DataSet.Tables[0]
Here is a function that I use (slightly redacted).这是我使用的一个函数(略有删节)。 It allows input and output parameters.
它允许输入和输出参数。 I only have uniqueidentifier and varchar types implemented, but any other types are easy to add.
我只实现了 uniqueidentifier 和 varchar 类型,但任何其他类型都很容易添加。 If you use parameterized stored procedures (or just parameterized sql...this code is easily adapted to that), this will make your life a lot easier.
如果您使用参数化存储过程(或只是参数化 sql...此代码很容易适应),这将使您的生活更轻松。
To call the function, you need a connection to the SQL server (say $conn),要调用该函数,您需要连接到 SQL 服务器(例如 $conn),
$res=exec-storedprocedure -storedProcName 'stp_myProc' -parameters @{Param1="Hello";Param2=50} -outparams @{ID="uniqueidentifier"} $conn
$res=exec-storedprocedure -storedProcName 'stp_myProc' -parameters @{Param1="Hello";Param2=50} -outparams @{ID="uniqueidentifier"} $conn
retrieve proc output from returned object
从返回的对象中检索 proc 输出
$res.data #dataset containing the datatables returned by selects
$res.data #dataset 包含选择返回的数据表
$res.outputparams.ID #output parameter ID (uniqueidentifier)
$res.outputparams.ID #输出参数ID(唯一标识符)
The function:功能:
function exec-storedprocedure($storedProcName,
[hashtable] $parameters=@{},
[hashtable] $outparams=@{},
$conn,[switch]$help){
function put-outputparameters($cmd, $outparams){
foreach($outp in $outparams.Keys){
$cmd.Parameters.Add("@$outp", (get-paramtype $outparams[$outp])).Direction=[System.Data.ParameterDirection]::Output
}
}
function get-outputparameters($cmd,$outparams){
foreach($p in $cmd.Parameters){
if ($p.Direction -eq [System.Data.ParameterDirection]::Output){
$outparams[$p.ParameterName.Replace("@","")]=$p.Value
}
}
}
function get-paramtype($typename,[switch]$help){
switch ($typename){
'uniqueidentifier' {[System.Data.SqlDbType]::UniqueIdentifier}
'int' {[System.Data.SqlDbType]::Int}
'xml' {[System.Data.SqlDbType]::Xml}
'nvarchar' {[System.Data.SqlDbType]::NVarchar}
default {[System.Data.SqlDbType]::Varchar}
}
}
if ($help){
$msg = @"
Execute a sql statement. Parameters are allowed.
Input parameters should be a dictionary of parameter names and values.
Output parameters should be a dictionary of parameter names and types.
Return value will usually be a list of datarows.
Usage: exec-query sql [inputparameters] [outputparameters] [conn] [-help]
"@
Write-Host $msg
return
}
$close=($conn.State -eq [System.Data.ConnectionState]'Closed')
if ($close) {
$conn.Open()
}
$cmd=new-object system.Data.SqlClient.SqlCommand($sql,$conn)
$cmd.CommandType=[System.Data.CommandType]'StoredProcedure'
$cmd.CommandText=$storedProcName
foreach($p in $parameters.Keys){
$cmd.Parameters.AddWithValue("@$p",[string]$parameters[$p]).Direction=
[System.Data.ParameterDirection]::Input
}
put-outputparameters $cmd $outparams
$ds=New-Object system.Data.DataSet
$da=New-Object system.Data.SqlClient.SqlDataAdapter($cmd)
[Void]$da.fill($ds)
if ($close) {
$conn.Close()
}
get-outputparameters $cmd $outparams
return @{data=$ds;outputparams=$outparams}
}
Here is a function I use to execute sql commands.这是我用来执行 sql 命令的函数。 You just have to change $sqlCommand.CommandText to the name of your sproc and $SqlCommand.CommandType to CommandType.StoredProcedure.
您只需要将 $sqlCommand.CommandText 更改为存储过程的名称,并将 $SqlCommand.CommandType 更改为 CommandType.StoredProcedure。
function execute-Sql{
param($server, $db, $sql )
$sqlConnection = new-object System.Data.SqlClient.SqlConnection
$sqlConnection.ConnectionString = 'server=' + $server + ';integrated security=TRUE;database=' + $db
$sqlConnection.Open()
$sqlCommand = new-object System.Data.SqlClient.SqlCommand
$sqlCommand.CommandTimeout = 120
$sqlCommand.Connection = $sqlConnection
$sqlCommand.CommandText= $sql
$text = $sql.Substring(0, 50)
Write-Progress -Activity "Executing SQL" -Status "Executing SQL => $text..."
Write-Host "Executing SQL => $text..."
$result = $sqlCommand.ExecuteNonQuery()
$sqlConnection.Close()
}
如果是 2005 数据库,请使用 sqlcmd 而不是 osql
Consider calling osql.exe (the command line tool for SQL Server) passing as parameter a text file written for each line with the call to the stored procedure.考虑调用 osql.exe(SQL Server 的命令行工具)作为参数传递一个文本文件,该文件是为调用存储过程的每一行编写的。
SQL Server provides some assemblies that could be of use with the name SMO that have seamless integration with PowerShell. SQL Server 提供了一些可与名称 SMO 一起使用的程序集,它们与 PowerShell 无缝集成。 Here is an article on that.
这是一篇关于此的文章。
http://www.databasejournal.com/features/mssql/article.php/3696731 http://www.databasejournal.com/features/mssql/article.php/3696731
There are API methods to execute stored procedures that I think are worth being investigated.有一些 API 方法可以执行存储过程,我认为这些方法值得研究。 Here a startup example:
这是一个启动示例:
http://www.eggheadcafe.com/software/aspnet/29974894/smo-running-a-stored-pro.aspx http://www.eggheadcafe.com/software/aspnet/29974894/smo-running-a-stored-pro.aspx
I include invoke-sqlcmd2.ps1
and write-datatable.ps1
from http://blogs.technet.com/b/heyscriptingguy/archive/2010/11/01/use-powershell-to-collect-server-data-and-write-to-sql.aspx .我包括来自http://blogs.technet.com/b/heyscriptingguy/archive/2010/11/01/use-powershell-to-collect-server-data-and-的
invoke-sqlcmd2.ps1
和write-datatable.ps1
写入到 sql.aspx 。 Calls to run SQL commands take the form:运行 SQL 命令的调用采用以下形式:
Invoke-sqlcmd2 -ServerInstance "<sql-server>" -Database <DB> -Query "truncate table <table>"
An example of writing the contents of DataTable variables to a SQL table looks like:将 DataTable 变量的内容写入 SQL 表的示例如下所示:
$logs = (get-item SQLSERVER:\sql\<server_path>).ReadErrorLog() Write-DataTable -ServerInstance "<sql-server>" -Database "<DB>" -TableName "<table>" -Data $logs
I find these useful when doing SQL Server database-related PowerShell scripts as the resulting scripts are clean and readable.我发现这些在执行 SQL Server 数据库相关的 PowerShell 脚本时很有用,因为生成的脚本干净且可读。
Adds CommandType
and Parameters
to @Santiago Cepas' answer:将
CommandType
和Parameters
添加到 @Santiago Cepas 的答案:
function Execute-Stored-Procedure
{
param($server, $db, $spname)
$sqlConnection = new-object System.Data.SqlClient.SqlConnection
$sqlConnection.ConnectionString = 'server=' + $server + ';integrated security=TRUE;database=' + $db
$sqlConnection.Open()
$sqlCommand = new-object System.Data.SqlClient.SqlCommand
$sqlCommand.CommandTimeout = 120
$sqlCommand.Connection = $sqlConnection
$sqlCommand.CommandType= [System.Data.CommandType]::StoredProcedure
# If you have paramters, add them like this:
# $sqlCommand.Parameters.AddWithValue("@paramName", "$param") | Out-Null
$sqlCommand.CommandText= $spname
$text = $spname.Substring(0, 50)
Write-Progress -Activity "Executing Stored Procedure" -Status "Executing SQL => $text..."
Write-Host "Executing Stored Procedure => $text..."
$result = $sqlCommand.ExecuteNonQuery()
$sqlConnection.Close()
}
# Call like this:
Execute-Stored-Procedure -server "enter-server-name-here" -db "enter-db-name-here" -spname "enter-sp-name-here"
I added timeout and show how to reader a scalar or get results using a reader我添加了超时并展示了如何读取标量或使用读取器获取结果
function exec-query( $storedProcName,$parameters=@{},$conn,$timeout=60){
$cmd=new-object system.Data.SqlClient.SqlCommand
$cmd.CommandType=[System.Data.CommandType]'StoredProcedure'
$cmd.Connection=$conn
$cmd.CommandText=$storedProcName
$cmd.CommandTimeout=$timeout
foreach($p in $parameters.Keys){
[Void] $cmd.Parameters.AddWithValue("@$p",$parameters[$p])
}
#$id=$cmd.ExecuteScalar()
$adapter=New-Object system.Data.SqlClient.SqlDataAdapter($cmd)
$dataset=New-Object system.Data.DataSet
$adapter.fill($dataset) | Out-Null
#$reader = $cmd.ExecuteReader()
#$results = @()
#while ($reader.Read())
#{
# write-host "reached" -ForegroundColor Green
#}
return $dataSet.Tables[0]
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.