Script - Abrir otra conexión y lanzar una stored con otro login.

Creado por David Miralpeix, Modificado el Fri, 16 Feb 2024 a las 12:28 PM por David Miralpeix

Ejecutar un stored procedure con una conexión distinta a la que está logueado el usuario del ERP.
Útil para cuando necesitamos permisos de otro usuario para, por ejemplo, lanzar una stored.


Código VB6:

' Esta función crea una nueva conexión a la base de datos con el usuario sa y lanza una stored con parámetros.
' Gentileza de nuestro compañero de AXIUM, Ioseba Gárate. ;)

Function Pers_ejecutaStore(nombre)
Dim conn: Set conn = CreateObject("ADODB.Connection")
conn.open "Driver={SQL Server};Server=DBSERVER\INSTANCIA;Database=MIDB;Uid=sa;Pwd=*********;"
Dim cmdUA
Set cmdUA = CreateObject("ADODB.Command")
Set cmdUA.ActiveConnection = conn
cmdUA.CommandText = nombre
cmdUA.CommandType = 4
Set Param = cmdUA.CreateParameter("NOMBRE_PARAMETRO", 3, 1, 8, "VALOR_DEL_PARAMETRO" )
cmdUA.Parameters.Append Param
Set rs = cmdUA.Execute
Pers_ejecutaStore= rs.Fields(0).Value
End Function


Código C#:

Para que sea más sencillo realizar pruebas se adjunta el código del procedure personalizado al que llamamos. Ejecutar en SQL Server:

CREATE PROCEDURE pPers_Crear_Cliente
(@IdCliente varchar(50), @NombreCliente varchar(250))
AS
BEGIN
SELECT * FROM Clientes_Datos
  INSERT INTO Clientes_Datos (IdCliente, Cliente, RazonSocial) 
  VALUES (@IdCliente, @NombreCliente, @NombreCliente)
 
END

Para la prueba de C# tendremos que referenciar ADODB y sus métodos y propiedades mediante Reflection. El ejemplo de Visual Basic, transcrito de esta forma a C# en un script vacío sería de la siguiente forma.

using AhoraCore;
using AhoraCl;
using AhoraOCX;
using System;
using static AhoraCore.VBA.Interaction;
using System.Reflection;
using AhoraSistema;

namespace AhoraScriptsVacia
{
    public class Script_58 : AhoraOCX.AhoraBaseScript
    {
        public void Main()
        {
            try
            {
                Type tipoConexion = Type.GetTypeFromProgID("ADODB.Connection");
                object lConn = System.Activator.CreateInstance(tipoConexion);

                Object[] parameters1 = new Object[1];
                Object[] parameters5 = new Object[5];

                parameters1[0] = "Driver={SQL Server};Server=NOMBRE_INSTANCIA_SQLSERVER;Database=NOMBRE_BBDD;Uid=NOMBRE_USUARIO;Pwd=-PASSWORD;";

                // Invocamos el método "Open" de "ADODB.Connection"
                tipoConexion.InvokeMember("Open", System.Reflection.BindingFlags.InvokeMethod, null, lConn, parameters1);

                Type tipoCommand = Type.GetTypeFromProgID("ADODB.Command");
                object lCommand = System.Activator.CreateInstance(tipoCommand);
                parameters1[0] = lConn;

                tipoCommand.InvokeMember("ActiveConnection", BindingFlags.SetProperty, null, lCommand, parameters1);

                // Invocamos el procedure
                parameters1[0] = "pPers_Crear_Cliente";
                tipoCommand.InvokeMember("CommandText", BindingFlags.SetProperty, null, lCommand, parameters1);
                parameters1[0] = 4;                         // Evaluates CommandText as a stored procedure name.
                tipoCommand.InvokeMember("CommandType", BindingFlags.SetProperty, null, lCommand, parameters1);
                
                // Añadimos los parámetros (configurándolos uno a uno)
                // ---------------------------------------------------

                // Parámetro "@IdCliente"
                parameters5[0] = "@IdCliente";          // Name
                parameters5[1] = 200;                   // Type (3 -> Integer, 200 -> Varchar) (https://learn.microsoft.com/en-us/sql/ado/reference/ado-api/datatypeenum?view=sql-server-ver16)
                parameters5[2] = 1;                     // Direction (1 -> adParamInput) (https://learn.microsoft.com/en-us/sql/ado/reference/ado-api/parameterdirectionenum?view=sql-server-ver16)
                parameters5[3] = 50;                    // Size
                parameters5[4] = "00098";               // Value
                object Param1 = tipoCommand.InvokeMember("CreateParameter", BindingFlags.InvokeMethod, null, lCommand, parameters5);
                object Parameters = tipoCommand.InvokeMember("Parameters", BindingFlags.GetProperty, null, lCommand, null);
                // Añadimos el parámetro
                parameters1[0] = Param1;
                tipoCommand.InvokeMember("Append", BindingFlags.InvokeMethod, null, Parameters, parameters1);

                // Parámetro "@IdCliente"
                parameters5[0] = "@NombreCliente";      // Name
                parameters5[1] = 200;                   // Type (3 -> Integer, 200 -> Varchar) (https://learn.microsoft.com/en-us/sql/ado/reference/ado-api/datatypeenum?view=sql-server-ver16)
                parameters5[2] = 1;                     // Direction (1 -> adParamInput) (https://learn.microsoft.com/en-us/sql/ado/reference/ado-api/parameterdirectionenum?view=sql-server-ver16)
                parameters5[3] = 250;                   // Size
                parameters5[4] = "Nombre Cliente";      // Value
                object Param2 = tipoCommand.InvokeMember("CreateParameter", BindingFlags.InvokeMethod, null, lCommand, parameters5);
                Parameters = tipoCommand.InvokeMember("Parameters", BindingFlags.GetProperty, null, lCommand, null);
                // Añadimos el parámetro
                parameters1[0] = Param2;
                tipoCommand.InvokeMember("Append", BindingFlags.InvokeMethod, null, Parameters, parameters1);

                // Ejecutamos el procedure y recuperamos el RecordSet que devuelve
                object lRes = tipoCommand.InvokeMember("Execute", BindingFlags.InvokeMethod, null, lCommand, null);
                
                // Recuperamos "lRes.Fields"
                object lFields = tipoCommand.InvokeMember("Fields", BindingFlags.GetProperty, null, lRes, null);
                
                // Recuperamos "lRes.Fields[0]"
                parameters1[0] = 0;
                object lField0 = tipoCommand.InvokeMember("Item", BindingFlags.InvokeMethod, null, lFields, parameters1);

                object lValue = tipoCommand.InvokeMember("Value", BindingFlags.GetProperty, null, lField0, null);

                MsgBox(lValue.ToString());


            }
            catch (Exception ex)
            {
                MsgBox("ERROR CONECTANDO: " + ex.Message);
                return;
            }

        }
    }
}

¿Le ha sido útil este artículo?

¡Qué bien!

Gracias por sus comentarios

¡Sentimos mucho no haber sido de ayuda!

Gracias por sus comentarios

¡Háganos saber cómo podemos mejorar este artículo!

Seleccione al menos una de las razones
Se requiere la verificación del CAPTCHA.

Sus comentarios se han enviado

Agradecemos su esfuerzo e intentaremos corregir el artículo