it-swarm-eu.dev

Wie rufe ich eine gespeicherte SQL Server-Prozedur von PowerShell aus auf?

Ich habe eine große CSV-Datei und möchte für jede Zeile eine gespeicherte Prozedur ausführen.

Was ist der beste Weg, um eine gespeicherte Prozedur von PowerShell aus auszuführen?

37
Andrew Jones

Diese Antwort wurde aus http://www.databasejournal.com/features/mssql/article.php/3683181 abgerufen.

Dasselbe Beispiel kann für beliebige Ad-hoc-Abfragen verwendet werden. Lassen Sie uns die gespeicherte Prozedur "sp_helpdb" wie unten gezeigt ausführen.

$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

Hier ist eine Funktion, die ich benutze (leicht geändert). Es erlaubt Eingabe- und Ausgabeparameter. Ich habe nur uniqueidentifier- und varchar-Typen implementiert, aber alle anderen Typen sind leicht hinzuzufügen. Wenn Sie parametrisierte gespeicherte Prozeduren verwenden (oder einfach nur parametrisierte SQL-Werte ... dieser Code kann leicht angepasst werden), wird dies Ihr Leben erheblich erleichtern.

Um die Funktion aufzurufen, benötigen Sie eine Verbindung zum SQL-Server (zB $ conn). 

$ res = exec-gespeicherteProzedur -storedProcName 'stp_myProc' -Parameter @ {Param1 = "Hallo"; Param2 = 50} -outparams @ {ID = "uniqueidentifier"} $ conn

Proc-Ausgabe vom zurückgegebenen Objekt abrufen

$ res.data #dataset, das die von selects zurückgegebenen Daten enthält

$ res.outputparams.ID #output parameter ID (uniqueidentifier)

Die Funktion:

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

Hier ist eine Funktion, die ich zum Ausführen von SQL-Befehlen verwende. Sie müssen lediglich $ sqlCommand.CommandText in den Namen Ihres Sprocs und $ SqlCommand.CommandType in CommandType.StoredProcedure ändern.

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

Verwenden Sie sqlcmd anstelle von osql, wenn es sich um eine 2005-Datenbank handelt

3
Galwegian

Erwägen Sie den Aufruf von osql.exe (Befehlszeilentool für SQL Server), und übergeben Sie als Parameter eine Textdatei, die für jede Zeile mit dem Aufruf der gespeicherten Prozedur geschrieben wurde.

SQL Server stellt einige Assemblys bereit, die unter dem Namen SMO von Nutzen sein könnten und eine nahtlose Integration mit PowerShell aufweisen. Hier ist ein Artikel dazu.

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

Es gibt API-Methoden zum Ausführen von gespeicherten Prozeduren, die meiner Meinung nach eine Untersuchung wert sind. Hier ein Startbeispiel:

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

2
Jorge Ferreira

Ich gebe invoke-sqlcmd2.ps1 und write-datatable.ps1 aus http://blogs.technet.com/b/heyscriptingguy/archive/2010/11/01/use-powershell-to-collect-server-data-and-write-to-sql ein. aspx . Aufrufe zum Ausführen von SQL-Befehlen haben folgende Form: 
Invoke-sqlcmd2 -ServerInstance "<sql-server>" -Database <DB> -Query "truncate table <table>" 
Ein Beispiel zum Schreiben des Inhalts von DataTable-Variablen in eine SQL-Tabelle sieht wie folgt aus: 
$logs = (get-item SQLSERVER:\sql\<server_path>).ReadErrorLog() Write-DataTable -ServerInstance "<sql-server>" -Database "<DB>" -TableName "<table>" -Data $logs
Ich finde diese nützlich, wenn Sie SQL Server-Datenbank-bezogene PowerShell-Skripts verwenden, da die resultierenden Skripts sauber und lesbar sind.

0
Ken