none
Crear función para saber tipo proceso almacenado RRS feed

  • Pregunta

  • Hola a todos:

    Preciso crear una función que entregue el tipo de proceso almacenado, es decir, que le pase el nombre únicamente del proceso y me detecte lo que tiene que aplicar. Estoy batallando con ella y no logro crearla correctamente.

    Por ejemplo, que una select cualquier que carga un proceso almacenado pueda leer solo con el nombre del proceso si tiene que aplicar un storeprocedure determinado o bien, aplicar la consulta select que figura en dicho proceso según la base de datos admita o no procesos almacenados.

     Public Shared Function ProcesoAlmacenado(ProcedAlmac As String, NombreProceso As String, ProcedString As String, TipoComando As String) As String
            Dim da As DataAccessInvariant = DataAccessInvariant.GetDataAccessInvariant(Configuracion.CadenaConexion)
    
            Using cnn As DbConnection = da.CreateConnection()
                Dim cmd As DbCommand = cnn.CreateCommand
    
                If (Configuracion.strNombreBaseDeDatos = "PerseoSqlCE" OrElse Configuracion.strNombreBaseDeDatos = "PerseoSQLite") Then
                    cmd.CommandType = CommandType.Text
                    'NombreProceso 'MetodosCreacion.CreacionprocFormulasBalance_4_ClaveMP()
                    cmd.CommandText = ProcedString   'strprocFormulasBalance4digMP
                Else
                    cmd.CommandType = CommandType.StoredProcedure
                    cmd.CommandText = ProcedString    '"procFormulasBalance4digMP"
                End If
            End Using
        End Function

    Me estoy haciendo hace rato un lío y no deshago la madeja.

    Un cordial saludo a todos.

    jueves, 11 de febrero de 2016 16:10

Respuestas

  • Hola:

    Al final lo he podido solucionar agrupando los tipos de procedimiento, les he metido una función y funciona perfectamente, ahorro todo el código que tenía que verificar en los métodos de las sentencias.

    lic Shared Function NombreProcInsercion(Nombre As String) As String
    
            Dim da As DataAccessInvariant = DataAccessInvariant.GetDataAccessInvariant(Configuracion.CadenaConexion)
            ' Declaramos una variable Connection
            Using cnn As DbConnection = da.CreateConnection()
    
                ' Creamos el Commando
                Dim cmd As DbCommand = cnn.CreateCommand
    
                Select Case Nombre
                    Case "CreacionProcInsercionVarios"
                        If (Configuracion.strNombreBaseDeDatos = "PerseoSqlCE" OrElse Configuracion.strNombreBaseDeDatos = "PerseoSQLite") Then
                            cmd.CommandType = CommandType.Text
                            MetodosCreacion.CreacionProcInsercionVarios()
                            cmd.CommandText = strProcInsercionVarios
                        Else
                            cmd.CommandType = CommandType.StoredProcedure
                            cmd.CommandText = "ProcInsercionVarios"
                        End If
    
                    Case "CreacionProcInsercionCapCirculante"
                        If (Configuracion.strNombreBaseDeDatos = "PerseoSqlCE" OrElse Configuracion.strNombreBaseDeDatos = "PerseoSQLite") Then
                            cmd.CommandType = CommandType.Text
                            MetodosCreacion.CreacionProcInsercionCapCirculante()
                            cmd.CommandText = strProcInsercionCapCirculante
                        Else
                            cmd.CommandType = CommandType.StoredProcedure
                            cmd.CommandText = "ProcInsercionCapCirculante"
                        End If
    .../.../

    Con ello hago únicamente una llamada desde el método que sea, por ejemplo:

    'Procedemos mediante este proceso a insertar los registros de las descripciones del balance
                MetodosCreacion.NombreProcInsercion("ProcInsercionVarios")

    Bueno, gracias a los dos por intentar solucionarlo.

    Un cordial saludo.

    Gemma

    • Marcado como respuesta gemma_campillo jueves, 11 de febrero de 2016 19:08
    jueves, 11 de febrero de 2016 19:08

Todas las respuestas

  • Hola:

     Creo que esto que deseas hacer es un poco complicado, quiero pensar que de alguna manera es posible tal cual como lo planteas.

     Lo que yo haría (viendo que usas Factorías para saber que motor de base de datos estas usando), seria crear dos métodos o funciones según aplique, uno para aquellos motores que permitan Stores Procedures y otro para aquellos que no lo permitan y en su lugar se requiera de ejecutar una consulta directamente. 

     La logica que seguiria seria:

    1. Cuando identifique por medio de las factorías que motor de base de datos se esta usando busco dentro de una lista aquellos motores que yo previamente halla confirmado puedan usar SP, si este motor coincide entonces prendo una bandera.

    2. Creo un método o una función según aplique la cual pregunte por el status de esta bandera, si esta prendida sabre entonces que debo de llamar a la rutina de codigo que usa el SP si no sabre que debo de llamar a la rutina que usa las consultas SQL explicitas.

    3. Mando a llamar las rutinas.

    Public Function XFunction(parametros) AS Clase
    	If(bandera)Then
    	 Return XFunction(parametros)
    	Else
    	 Return XFunction2(parametros)
    	End If
    End Function
    
    Private Function XFunction(parametros) As Clase
    	'Logica que usa SP
    End Sub
    
    Private Sub XFunction2(parametros)
     'Logica que usa consulta implicita
    End Sub
    Mas o menos haría algo así.


    Saludos desde Monterrey, Nuevo León, México!!!

    jueves, 11 de febrero de 2016 16:36
  • Hola José Luis, un placer volver a hablar contigo.

    Bueno, efectivamente usos factorías y tengo (para aprovechar lo que tenia ya hecho) "x" procesos almacenados. En el mismo según sea la base de datos cargo el procedimiento o bien un String con el select o update según sea el procedimiento.

    te pongo uno pequeño de solo 1 dígito para que te hagas una idea. Te comento que Oracle y sqlite tengo que acabarlos de probar.

      Public Shared Sub CreacionProcFlujosEfect_1_Dig()
            If (Configuracion.strNombreBaseDeDatos = "PerseoSqlCE" OrElse Configuracion.strNombreBaseDeDatos = "PerseoSQLite") <> True Then
                Dim bln As Boolean = ExisteProcedure("procFlujEfectivo1dig")
                If bln = True Then Return
            End If
    
            Dim da As DataAccessInvariant = DataAccessInvariant.GetDataAccessInvariant(Configuracion.CadenaConexion)
    
            Using cnn As DbConnection = da.CreateConnection()
                Dim cmd As DbCommand = cnn.CreateCommand
    
                'Creación de procedimiento almacenado para "SELECT"
    
                If Configuracion.strNombreBaseDeDatos = "MiCadenaConexion" = True Then
                    cmd.CommandText = "CREATE PROCEDURE procFlujEfectivo1dig " & _
                                 "([@empresa] Text(3), [@planconta] Text(12), [@codigo1] Text(7))) AS " & _
                                 "SELECT Ejer_01, Ejer_02 " & _
                                 "FROM Balances WHERE idEmpresa = [@empresa] AND PlanConta = [@planconta] " & _
                                 "AND [Cód_GC] = [@codigo1]"
                   
                ElseIf Configuracion.strNombreBaseDeDatos = "PerseoSqlEx" = True Then
                    cmd.CommandText = "CREATE PROCEDURE dbo.procFlujEfectivo1dig  " & _
                                "@empresa Nvarchar(3), @planconta Nvarchar(12), @codigo1 Nvarchar(7)  " & _
                                "AS " & _
                                "SELECT Ejer_01, Ejer_02  " & _
                                "FROM Balances WHERE IdEmpresa = @empresa AND PlanConta = @planconta " & _
                                "AND Cód_GC = @codigo1"
    
                ElseIf Configuracion.strNombreBaseDeDatos = "PerseoSqlCE" = True Then
                    strprocFlujEfectivo1dig = "SELECT Ejer_01, Ejer_02 " & _
                                "FROM Balances WHERE IdEmpresa = @empresa AND PlanConta = @planconta " & _
                                "AND Cód_GC = @codigo1"
                    Exit Sub
    
                ElseIf Configuracion.strNombreBaseDeDatos = "PerseoMySQL" = True Then
                    cmd.CommandText = " CREATE DEFINER=`root`@`localhost` PROCEDURE `procFlujEfectivo1dig`(" & _
                                "empresa Nvarchar(3), planconta Nvarchar(12), codigo1 Nvarchar(7)) " & _
                                " BEGIN " & _
                                "SELECT Ejer_01, Ejer_02 " & _
                                "FROM Balances WHERE IdEmpresa = empresa AND PlanConta = planconta " & _
                                "AND Cód_GC = codigo1; " & _
                                "End"
    
                ElseIf Configuracion.strNombreBaseDeDatos = "PerseoSQLite" = True Then
                    strprocFlujEfectivo1dig = "SELECT Ejer_01, Ejer_02 " & _
                                "FROM Balances WHERE IdEmpresa = @empresa AND PlanConta = @planconta " & _
                                "AND Cód_GC = @codigo1"
                    Exit Sub
    
                ElseIf Configuracion.strNombreBaseDeDatos = "PerseoOracle" = True Then
                    cmd.CommandText = " CREATE PROCEDURE procFlujEfectivo1dig(" & _
                                "empresa Nvarchar(3), planconta Nvarchar(12), codigo1 Nvarchar(7)) " & _
                                " BEGIN() AS " & _
                                "SELECT Ejer_01, Ejer_02 " & _
                                "FROM Balances WHERE IdEmpresa = empresa AND PlanConta = planconta " & _
                                "AND Cód_GC = codigo1; " & _
                                "End;"
    
                End If
    
                cnn.Open()
                cmd.ExecuteNonQuery()
            End Using
        End Sub

    Cuando llamo desde cualquier clase de la capa "lógica", simplemente en el commandes text, le pongo el nombre del procedimiento y ya está. Por ello, querría continbuar poniéndole solamente el nombre del procedimiento y no tener que verificar en cada uno si es un storeproductore o un String en caso de que no lleve procedimientos almacenados.

    Es por eso que quiero crear una función que le pase solamente el nombre del procedimiento y ella vea por donde tiene que ir, ya que detectaría la función si es un storeprocedure o una Select por ejemplo. Y ahí me he hecho un lío y como estoy espesa no acabo de ver la solución. Por ejepmlo si la pruebo en el cálculo de una Select puedo hacer lo siguiente:

     Public Shared Sub FormBalances_ActivosPorImpuestoDiferido_ANC()
            'Creamos el acceso a datos mediante el nombre de la cadena de conexión existente en el archivo de configuración de la aplicación.
            Dim da As DataAccessInvariant = DataAccessInvariant.GetDataAccessInvariant(Configuracion.CadenaConexion)
            Dim valor As Integer = AccesoLogica.ObtenerPeriodos()
            Dim i As Int32
    
            ' Declaramos una variable Connection
            Using cnn As DbConnection = da.CreateConnection()
    
                ' Creamos el Commando
                Dim cmd As DbCommand = cnn.CreateCommand()
    
                cmd.CommandType = CommandType.StoredProcedure
    
                cnn.Open()
    
                ReDim ActivosPorImpuestoDiferido_ANC(ActivosPorImpuestoDiferido_ANC.Length - 1)
    
                If VarGlobal.StrCodPais = "34" Then
                    If VarGlobal.StrPlanConta = "PLAN 2007" Then
    
                        If (Configuracion.strNombreBaseDeDatos = "PerseoSqlCE" OrElse Configuracion.strNombreBaseDeDatos = "PerseoSQLite") Then
                            cmd.CommandType = CommandType.Text
                            MetodosCreacion.CreacionprocFormulasBalance_4_digitos()
                            cmd.CommandText = MetodosCreacion.strprocFormulasBalance4Dig
                        Else
                            cmd.CommandType = CommandType.StoredProcedure
                            cmd.CommandText = "procFormulasBalance4dig"
                        End If
    
                        With cmd.Parameters
                            .Clear()
                            .Add(Configuracion.CreateParameter(cmd, "@empresa", VarGlobal.StrCodEmpresa))
                            .Add(Configuracion.CreateParameter(cmd, "@planconta", "PLAN 2007"))
                            .Add(Configuracion.CreateParameter(cmd, "@codigo1", "474"))
                            .Add(Configuracion.CreateParameter(cmd, "@codigo2", "4740"))
                            .Add(Configuracion.CreateParameter(cmd, "@codigo3", "4742"))
                            .Add(Configuracion.CreateParameter(cmd, "@codigo4", "4745"))
                        End With
    
                    ElseIf VarGlobal.StrPlanConta = "FISCAL" Then
                        If (Configuracion.strNombreBaseDeDatos = "PerseoSqlCE" OrElse Configuracion.strNombreBaseDeDatos = "PerseoSQLite") Then
                            cmd.CommandType = CommandType.Text
                            MetodosCreacion.CreacionprocFormulasBalance_1_digitos()
                            cmd.CommandText = MetodosCreacion.strprocFormulasBalance1dig
                        Else
                            cmd.CommandType = CommandType.StoredProcedure
                            cmd.CommandText = "procFormulasBalance1dig"
                        End If
    
                        With cmd.Parameters
                            .Clear()
                            .Add(Configuracion.CreateParameter(cmd, "@empresa", VarGlobal.StrCodEmpresa))
                            .Add(Configuracion.CreateParameter(cmd, "@planconta", "FISCAL"))
                            .Add(Configuracion.CreateParameter(cmd, "@codigo1", "11600"))
                        End With
    
                    Else
                        Return
                    End If
    
                Else
                    Return
                End If
    
                Using dr As DbDataReader = cmd.ExecuteReader()
                    While dr.Read
                        For i = 0 To valor
                            ActivosPorImpuestoDiferido_ANC(i) += dr.GetDouble(i)
                        Next i
                    End While
                End Using
    
                '///////////////////////
    ......
    End sub

    Pero, si tengo que ir añadiendo el mismo código en las 3000 selects que hay pues no veas. Bueno, no se si eso  da mas luz, de cualquier forma voy a seguir probando. Entiendo que en una sola función tendría que salir y solamente pasarle en principio, el nombre del proceso almacenado "CreacionProcFlujosEfect_1_Dig" para aprovechar el del ejemplo.

    Bueno querido Luis, te envío un fuerte abrazo.

    Gemma

    jueves, 11 de febrero de 2016 16:57
  • la verdad veo un poco compliocado lo que deseas hacer, ya que dentro de un proceso almacenado podes seleccionar, inserta, borrar y actualizar todo en un solo SP.

    lo que veo mas factible es que si dentro de un SP tenes todas las funcciones pongas un IF para ver que metodo funcion ejecutaras (CRUD)

    desde el sistema le tendrias que enviar el nombre del SP, los parametros y dentro de esos parametros el especial que te definira que funcion ejecutara

    lo otro seria que para hacer un select sea un SP(SP_AlgoSelect), para un Delete otro SP(SP_AlgoDelete), para un Insert Otro SP(SP_AlgoInsert) y para un Update otro SP(SP_AlgoUpdate)

    si queres saber lo que tiene internamente un sp podes utlizar el sp_helptext y recorrer linea por linea ahi tambien prodrias determinar que funciones (CRUD) tiene

    nose si me doy a explicar???


    Att. Franklin Andino

    jueves, 11 de febrero de 2016 17:02
  • Hola:

    Al final lo he podido solucionar agrupando los tipos de procedimiento, les he metido una función y funciona perfectamente, ahorro todo el código que tenía que verificar en los métodos de las sentencias.

    lic Shared Function NombreProcInsercion(Nombre As String) As String
    
            Dim da As DataAccessInvariant = DataAccessInvariant.GetDataAccessInvariant(Configuracion.CadenaConexion)
            ' Declaramos una variable Connection
            Using cnn As DbConnection = da.CreateConnection()
    
                ' Creamos el Commando
                Dim cmd As DbCommand = cnn.CreateCommand
    
                Select Case Nombre
                    Case "CreacionProcInsercionVarios"
                        If (Configuracion.strNombreBaseDeDatos = "PerseoSqlCE" OrElse Configuracion.strNombreBaseDeDatos = "PerseoSQLite") Then
                            cmd.CommandType = CommandType.Text
                            MetodosCreacion.CreacionProcInsercionVarios()
                            cmd.CommandText = strProcInsercionVarios
                        Else
                            cmd.CommandType = CommandType.StoredProcedure
                            cmd.CommandText = "ProcInsercionVarios"
                        End If
    
                    Case "CreacionProcInsercionCapCirculante"
                        If (Configuracion.strNombreBaseDeDatos = "PerseoSqlCE" OrElse Configuracion.strNombreBaseDeDatos = "PerseoSQLite") Then
                            cmd.CommandType = CommandType.Text
                            MetodosCreacion.CreacionProcInsercionCapCirculante()
                            cmd.CommandText = strProcInsercionCapCirculante
                        Else
                            cmd.CommandType = CommandType.StoredProcedure
                            cmd.CommandText = "ProcInsercionCapCirculante"
                        End If
    .../.../

    Con ello hago únicamente una llamada desde el método que sea, por ejemplo:

    'Procedemos mediante este proceso a insertar los registros de las descripciones del balance
                MetodosCreacion.NombreProcInsercion("ProcInsercionVarios")

    Bueno, gracias a los dos por intentar solucionarlo.

    Un cordial saludo.

    Gemma

    • Marcado como respuesta gemma_campillo jueves, 11 de febrero de 2016 19:08
    jueves, 11 de febrero de 2016 19:08