Principales respuestas
Crear función para saber tipo proceso almacenado

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.
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
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!!!
-
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
-
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
-
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