¿Cómo puedo llamar a un procedimiento almacenado de SQL Server desde PowerShell?

StackOverflow https://stackoverflow.com/questions/83410

  •  01-07-2019
  •  | 
  •  

Pregunta

Tengo un gran archivo CSV y quiero ejecutar un procedimiento almacenado para cada línea.

¿Cuál es la mejor manera de ejecutar un procedimiento almacenado desde PowerShell?

¿Fue útil?

Solución

Esta respuesta fue retirado de http://www.databasejournal.com/features/mssql/article.php/3683181

Este mismo ejemplo puede ser utilizado para cualquier consultas adhoc.Nos deja ejecutar el procedimiento almacenado "sp_helpdb" como se muestra a continuación.

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

Otros consejos

Aquí es una función que yo uso (ligeramente censurada).Se permite que los parámetros de entrada y salida.Sólo tengo uniqueidentifier y varchar tipos implementado, sino de cualquier otro tipo son fáciles de agregar.Si el uso de procedimientos almacenados con parámetros (o simplemente sql con parámetros...este código se adapta fácilmente a), esto hará que tu vida sea mucho más fácil.

Para llamar a la función, se necesita una conexión a SQL server (por ejemplo, de $conn),

$res=exec-storedprocedure -storedProcName 'stp_myProc' parámetros- @{Param1="Hola";Param2=50} -outparams @{ID="uniqueidentifier"} $conn

recuperar proc salida de objeto devuelto

$res.#de datos conjunto de datos que contiene las tablas de datos devuelto por selecciona

$res.outputparams.ID #parámetro de salida ID (uniqueidentifier)

La función:

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

Aquí es una función que uso para ejecutar comandos sql.Solo tienes que cambiar $sqlCommand.CommandText el nombre del procedimiento almacenado y $SqlCommand.CommandType a 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()
}

El uso de sqlcmd, en vez de osql si se trata de un 2005 de la base de datos

Considere la posibilidad de llamar a osql.exe (la herramienta de línea de comandos de SQL Server), pasando como parámetro un archivo de texto escrito para cada línea con la llamada al procedimiento almacenado.

SQL Server proporciona algunos de los ensamblados que podrían ser de utilidad con el nombre SMO que tiene una perfecta integración con PowerShell.Aquí está un artículo sobre eso.

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

Hay métodos de la API para ejecutar procedimientos almacenados que yo creo que vale la pena ser investigado.Aquí un inicio ejemplo:

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

Yo incluyen invoke-sqlcmd2.ps1 y 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.Las llamadas a ejecutar comandos SQL tomar la forma:
Invoke-sqlcmd2 -ServerInstance "<sql-server>" -Database <DB> -Query "truncate table <table>"
Un ejemplo de la redacción de los contenidos de DataTable variables de una tabla de SQL parece:
$logs = (get-item SQLSERVER:\sql\<server_path>).ReadErrorLog() Write-DataTable -ServerInstance "<sql-server>" -Database "<DB>" -TableName "<table>" -Data $logs
Me parece que estos útil cuando se hace de SQL Server base de datos relacionados con los scripts de PowerShell como la resultante de las secuencias de comandos son claras y legibles.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top