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

        }
    }
}