it-swarm-vi.tech

Làm cách nào để gọi thủ tục lưu trữ SQL Server từ PowerShell?

Tôi có một tệp CSV lớn và tôi muốn thực hiện một quy trình được lưu trữ cho mỗi dòng.

Cách tốt nhất để thực hiện một thủ tục được lưu trữ từ PowerShell là gì?

37
Andrew Jones

Câu trả lời này đã được lấy từ http://www.databasejournal.com/features/mssql/article.php/3683181

Ví dụ tương tự này có thể được sử dụng cho bất kỳ truy vấn adhoc nào. Hãy để chúng tôi thực hiện thủ tục được lưu trữ, sp sphhelpdb, như được hiển thị bên dưới.

$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]
57
Mark Schill

Đây là một chức năng mà tôi sử dụng (hơi được điều chỉnh lại). Nó cho phép các tham số đầu vào và đầu ra. Tôi chỉ có các loại nhận dạng duy nhất và varchar được triển khai, nhưng bất kỳ loại nào khác đều dễ dàng thêm vào. Nếu bạn sử dụng các thủ tục lưu trữ được tham số hóa (hoặc chỉ tham số sql ... mã này dễ dàng thích nghi với điều đó), điều này sẽ làm cho cuộc sống của bạn dễ dàng hơn rất nhiều.

Để gọi hàm, bạn cần kết nối với máy chủ SQL (giả sử $ Conn), 

$ res = exec-archiveprocedure -storedProcName 'stp_myProc' -parameter @ {Param1 = "Hello"; Param2 = 50} -outparams @ {ID = "uniqueidentifier"} $ Conn

truy xuất đầu ra Proc từ đối tượng trả về

$ res.data #dataset chứa các dữ liệu được trả về bởi các lựa chọn

$ res.outputparams.ID #output ID tham số (mã định danh duy nhất)

Chức năng:

function exec-storedprocedure($storedProcName,  
        [hashtable] [email protected]{},
        [hashtable] [email protected]{},
        $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}
    }
8
Mike Shepard

Đây là một chức năng tôi sử dụng để thực hiện các lệnh sql. Bạn chỉ cần đổi $ sqlCommand.CommandText thành tên của sproc và $ SqlCommand.CommandType thành 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()
}
6
Santiago Cepas

Sử dụng sqlcmd thay vì osql nếu đó là cơ sở dữ liệu năm 2005

3
Galwegian

Xem xét việc gọi osql.exe (công cụ dòng lệnh cho SQL Server) chuyển qua tham số một tệp văn bản được viết cho mỗi dòng với lệnh gọi đến thủ tục được lưu trữ.

SQL Server cung cấp một số hội đồng có thể được sử dụng với tên SMO có tích hợp liền mạch với PowerShell. Đây là một bài viết về điều đó.

http://www.databasejournal.com/features/mssql/article.php/3696731

Có các phương thức API để thực thi các thủ tục được lưu trữ mà tôi nghĩ là đáng để nghiên cứu. Dưới đây là một ví dụ khởi động:

http://www.eggheadcafe.com/software/aspnet/29974894/smo-rucky-a-stored-pro.aspx

2
Jorge Ferreira

Tôi bao gồm invoke-sqlcmd2.ps1write-datatable.ps1 từ http://bloss.technet.com/b/heyscriptingguy/archive/2010/11/01/use-powershell-to-collect-server-data-and-write-to-sql. aspx . Các lệnh gọi để chạy các lệnh SQL có dạng: 
Invoke-sqlcmd2 -ServerInstance "<sql-server>" -Database <DB> -Query "truncate table <table>" 
Một ví dụ về cách viết nội dung của các biến DataTable vào bảng SQL trông như sau: 
$logs = (get-item SQLSERVER:\sql\<server_path>).ReadErrorLog() Write-DataTable -ServerInstance "<sql-server>" -Database "<DB>" -TableName "<table>" -Data $logs
Tôi thấy những điều này hữu ích khi thực hiện các tập lệnh PowerShell liên quan đến cơ sở dữ liệu SQL Server vì các tập lệnh kết quả là sạch và có thể đọc được.

0
Ken