Question

J'ai un gros fichier CSV et je souhaite exécuter une procédure stockée pour chaque ligne.

Quel est le meilleur moyen d'exécuter une procédure stockée à partir de PowerShell?

Était-ce utile?

La solution

Cette réponse a été extraite de http://www.databasejournal.com/features /mssql/article.php/3683181

Ce même exemple peut être utilisé pour toutes les requêtes ad hoc. Exécutons la procédure stockée & # 8220; sp_helpdb & # 8221; comme indiqué ci-dessous.

$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]

Autres conseils

Voici une fonction que j’utilise (légèrement rédigée). Il permet les paramètres d'entrée et de sortie. Je n'ai que les types uniqueidentifier et varchar mis en œuvre, mais tous les autres types sont faciles à ajouter. Si vous utilisez des procédures stockées paramétrées (ou tout simplement sql paramétré ... ce code s’adapte facilement à cela), cela vous facilitera grandement la vie.

Pour appeler la fonction, vous devez disposer d'une connexion au serveur SQL (disons $ conn),

.
  

$ res = proc-stockée-exec -storedProcName 'stp_myProc' -parameters @ {Param1 = & "Bonjour &"; Param2 = 50} -outparams @ {ID = & "identificateur unique quot;} $ conn

     

récupérer la sortie proc de l'objet renvoyé

     

$ res.data #dataset contenant les données retournées par selects

     

$ res.outputparams.ID # ID de paramètre de sortie (identificateur unique)

La fonction:

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}
    }

Voici une fonction que j'utilise pour exécuter des commandes SQL. Il vous suffit de remplacer $ sqlCommand.CommandText par le nom de votre sproc et $ SqlCommand.CommandType par 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()
}

Utilisez sqlcmd au lieu de osql s'il s'agit d'une base de données 2005

Envisagez d'appeler osql.exe (l'outil de ligne de commande de SQL Server) en transmettant en paramètre un fichier texte écrit pour chaque ligne avec l'appel de la procédure stockée.

SQL Server fournit des assemblys pouvant être utilisés sous le nom SMO et s'intégrant parfaitement à PowerShell. Voici un article à ce sujet.

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

Il existe des méthodes API permettant d’exécuter des procédures stockées qui méritent d’être examinées. Voici un exemple de démarrage:

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

J'inclus invoke-sqlcmd2.ps1 et write-datatable.ps1 de http://blogs.technet.com/b/heyscriptingguy/archive/2010/11/01/use-powershell-to-collect-server- data-and-write-to-sql.aspx . Les appels à exécuter des commandes SQL se présentent sous la forme suivante:
Invoke-sqlcmd2 -ServerInstance "<sql-server>" -Database <DB> -Query "truncate table <table>"
Un exemple d’écriture du contenu des variables DataTable dans une table SQL ressemble à ceci:
$logs = (get-item SQLSERVER:\sql\<server_path>).ReadErrorLog() Write-DataTable -ServerInstance "<sql-server>" -Database "<DB>" -TableName "<table>" -Data $logs
Je trouve ces informations utiles lors de l’exécution de SQL Les scripts PowerShell liés à la base de données du serveur, car les scripts résultants sont propres et lisibles.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top