我有一个大的CSV文件,我想为每一行执行存储过程.
从PowerShell执行存储过程的最佳方法是什么?
这个答案来自http://www.databasejournal.com/features/mssql/article.php/3683181
此相同的示例可用于任何特殊查询.让我们执行存储过程"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]
这是我使用的功能(略微编辑).它允许输入和输出参数.我只实现了uniqueidentifier和varchar类型,但任何其他类型都很容易添加.如果你使用参数化存储过程(或只是参数化的sql ...这个代码很容易适应),这将使你的生活更轻松.
要调用该函数,您需要连接到SQL服务器(比如$ conn),
$ res = exec-storedprocedure -storedProcName'stp_myProc'-parameters @ {Param1 ="Hello"; Param2 = 50} -outparams @ {ID ="uniqueidentifier"} $ conn
从返回的对象检索proc输出
$ res.data #dataset包含由选择返回的数据表
$ res.outputparams.ID #output参数ID(uniqueidentifier)
功能:
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} }
这是我用来执行sql命令的函数.您只需将$ sqlCommand.CommandText更改为您的sproc的名称,并将$ 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() }