Visual Basic.NET - Armador dinámico de sentencias sql

 
Vista:
sin imagen de perfil

Armador dinámico de sentencias sql

Publicado por Nicolas (11 intervenciones) el 13/09/2015 19:57:54
Hola, estoy con un proyecto académico de egreso en el cual estoy teniendo algunas dificultades con la parte de programación.
Los requisitos del mismo apuntan a armar un sistema de facturación para lo que sería una tienda de informática, utilizando una base de datos remota con motor MySQL (ya esta armada y en un servidor) y la cuestión ahora es la parte de funciones para que se realicen altas, bajas y modificaciones.
Las consultas en la BD que desarrollamos no son complejas, la cuestión es como generalizar todas las búsquedas posibles en una función sola y no armar una función por cada caso de uso de búsqueda (osea cada tabla distinta con sus atributos, como pueden ser Usuarios, Clientes, etc).

Obviamente que al querer generalizar, se esta programando por capas, ya se logro un login exitosamente. Ahora la cuestión es como llegar a esto para tener una función genérica:


[Comando][Atributos] FROM [tablas] Where [condicion]

Motor de Búsqueda

Comando siempre es Select para este caso
Atributos es un elemento VARIABLE
FROM
[tabla] es un elemento VARIABLE
Siempre se utilizará Where para estos casos de busqueda
[Condicion] es un elemento VARIABLE

Se supone que dentro de la condición es donde se igualan los atributos a las variables (ingresos de usuario en los controles)
Atributos es la deteccion de los atributos de la base de datos que se seleccionan, cuando los mismos no sean vacios (en el programa, cuando el usuario ingresa texto en cada uno de ellos)
La otra cuestión es la detección automática de la tabla a utilizar.

Dentro de lo que sería la función llamada "MotorBusquedas", si alguien tiene alguna idea con este tipo de situaciones, voy a estar muy agradecido (aunque sea una idea de como encararlo).
Saludos
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
sin imagen de perfil

Armador dinámico de sentencias sql

Publicado por David (45 intervenciones) el 14/09/2015 10:52:59
Si las consultas son tan simples como dices, casi haría más ilegible tu código si haces un método para montar una consulta.
También depende cómo quieras montar la consulta, pero por lo que expones con un String.Format() creo que te vale de sobra.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Armador dinámico de sentencias sql

Publicado por Nicolas (11 intervenciones) el 15/09/2015 01:14:49
Pero como se implementa la funcion String.Format() y que utilidad tendría en si?
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Armador dinámico de sentencias sql

Publicado por David (45 intervenciones) el 15/09/2015 03:42:30
Declaras las plantillas de consultas a nivel de módulo
1
2
Const plantillaConsulta As String = "SELECT * FROM {0}"
Const plantillaConsultaConWhere As String = "SELECT * FROM {0} WHERE {1}"

Luego, donde quieras montar tu consulta, por ejemplo la que has puesto:
Select * from [tabla] where [atributo1='hola', atributo2='chau']

La montarías así:
1
Dim consulta As String = String.Format(plantillaConsultaConWhere, "[tabla]", "[atributo1='hola', atributo2='chau']")
Con valores de controles (dos supuestos TextBox llamados txt1 y txt2):
1
Dim consulta As String = String.Format(plantillaConsultaConWhere, "[tabla]", "[atributo1='" + txt1.Text + "', atributo2='" + txt2.Text + "']")
O
1
Dim consulta As String = String.Format(plantillaConsultaConWhere, "[tabla]", String.Concat("[atributo1='", txt1.Text, "', atributo2='", txt2.Text, "']"))
O
1
Dim consulta As String = String.Format(plantillaConsultaConWhere, "[tabla]", String.Format("[atributo1='{0}', atributo2='{1}']", txt1.Text, txt2.Text))
Esta es la forma que veo más sencilla. De aquí ya puedes complicarlo lo que quieras...
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Wilfredo Patricio Castillo
Val: 1.239
Bronce
Ha mantenido su posición en Visual Basic.NET (en relación al último mes)
Gráfica de Visual Basic.NET

Armador dinámico de sentencias sql

Publicado por Wilfredo Patricio Castillo (720 intervenciones) el 14/09/2015 18:36:00
No te sirva usar Entity Framewor?.

Si lo tienes en capas y utilizas entity framework se te facilitaría el asunto, aplicas el patrón repositorio con inyección de dependencias y listo.

Saludos cordiales
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Armador dinámico de sentencias sql

Publicado por Nicolas (11 intervenciones) el 15/09/2015 01:16:04
Soy novicio en vb.net, no conozco librerias que puedan servir de ayuda para esto, a que te referis con Entity Framework?
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de giancarlo
Val: 377
Bronce
Ha mantenido su posición en Visual Basic.NET (en relación al último mes)
Gráfica de Visual Basic.NET

Armador dinámico de sentencias sql

Publicado por giancarlo (488 intervenciones) el 14/09/2015 18:41:15
Es decir lo que tu quieres que te salga algo asi como el linq? pero para mysql. No conozco exactamente como hacerlo, pero se me ocurre que lo hagas con dataset, ahi puedes hacer algo parecido al llamar por codigo, otra cosa es usar Enum, pero solo es la idea, no sabria implementarlo, pero te doy la idea, solo valdria por tabla, no universal

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
dim vColumna()as string{"idFactura","cliente","direccion","item","registro"}
enum columna
idFactura=0
cliente=2
direccion=3
item=4
registro=5
end enum
 
dim vComando()as string={"select","where"}
enum comando
select=0
where=1
end enum
 
sub generarComando(co as comando,nomColumna as columna)
dim coman as string=vComando(co) & " " & vColumna(nomColumn) & "etc"
end sub

Hay que aumentarlo bastante, por cierto, aun asi, me parece mejor hacer una clase por tabla y dentro hacerle los sub o function que sean necesarios para que generes tus consultas de la BD
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Armador dinámico de sentencias sql

Publicado por Nicolas (11 intervenciones) el 15/09/2015 01:32:30
Me referiria mas bien a esto
Conformación de la consulta:
Siempre selecciono todos los atributos, osea filas enteras, eso esta mal en el post
Select * from [tabla] where [atributo1='hola', atributo2='chau']

Por lo tanto lo variable aca son la tabla y la condición unicamente
Llegando adecuadamente los datos como argumentos de la función no es problema ninguno armar un string recolectando datos con funciones de cadena, etc

El problema reside en la llegada de los argumentos en cuanto a los atributos, y el contenido de los mismos (lo que tipeo el usuario)
Ubicar a que tabla me estoy refiriendo no es tan complicado, porque la funcion se va a llamar muchas veces desde lugares distintos, entonces al llamarla le paso un argumento de tabla llamado "Usuario" como ejemplo, que será el utilizado en la consulta.

En definitiva la mayor complicación reside en que atributos necesito ubicar en la condicion (no nulos) y además como enlazar los textbox a los atributos en la base de datos.

Aunque también podría colocar todos los atributos en la condicion si existiera algun comodin como ser este:
Select * from [tabla] where [atributo1='hola', atributo2='chau']
Select * from [tabla] where [atributo1='hola', atributo2='*']
De esta forma el atributo2 es inexistente en la consulta, porque no importa su valor.

Otro concepto que me sugirieron es utilizar la encapsulación, aunque desconosco su sintaxis de implementación y no se si podra servirme especialmente para este caso:
cuando desconosco el numero de parametros, simplemente puedo pasar un objeto llamado Clientes de una clase creada por mi mismo (ejemplo), que contenga todos los atributos dentro, y ya con los valores, mediante los metodos set y get.

Esto es todo una lluvia de ideas, esta algo complicado de todas formas, en cuanto a tu ejemplo, creo que sería mejor armar todo en una función sola, quizá de esta forma no se vuelva tan complejo por el manejo de tantos retornos.
La cuestion esta simplemente en la llegada y la manipulación de los datos para ejecutar la consulta
Gracias, saludos
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Wilfredo Patricio Castillo
Val: 1.239
Bronce
Ha mantenido su posición en Visual Basic.NET (en relación al último mes)
Gráfica de Visual Basic.NET

Armador dinámico de sentencias sql

Publicado por Wilfredo Patricio Castillo (720 intervenciones) el 15/09/2015 13:20:39
Para tu caso, así como lo planteas, la solución es lo que ya dije en el post anterior.

Entity Framework, patrón repository con eso haces inyección de dependencias y te olvidas del problema.


Saludos cordiales
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar