texto studio regulares regular regexp_like management expresiones expresion ejemplo con sql regex unit-testing

studio - replace con expresiones regulares sql server



¿Expresión regular para coincidir con la sintaxis SQL común? (12)

Estaba escribiendo algunas pruebas unitarias la semana pasada para un fragmento de código que generó algunas declaraciones SQL.

Estaba tratando de encontrar una expresión regular para que coincida con la sintaxis SELECT, INSERT y UPDATE para poder verificar que mis métodos generaban SQL válido, y después de 3-4 horas de búsqueda y perder el tiempo con varios editores de expresiones regulares me rendí.

Logré obtener coincidencias parciales, pero debido a que una sección entre comillas puede contener cualquier carácter, se expande rápidamente para coincidir con la declaración completa.

Cualquier ayuda sería apreciada, no soy muy buena con las expresiones regulares, pero me gustaría aprender más sobre ellas.

Por cierto, es C # regex lo que estoy buscando.

Aclaración

No quiero tener acceso a una base de datos ya que esto es parte de una prueba de Unidad y no quiero tener que mantener una base de datos para probar mi código. que puede vivir más tiempo que el proyecto.


¿Has probado los selectores perezosos? En lugar de coincidir tanto como sea posible, coinciden lo menos posible, que es probablemente lo que necesita para las comillas.


Fuera de mi cabeza: ¿no podrías pasar el SQL generado a una base de datos y usar EXPLAIN en ellos y capturar cualquier excepción que indique que el SQL está mal formado?


No creo que necesite siquiera tener el esquema creado para poder validar la declaración, porque el sistema no intentará resolver object_name, etc. hasta que haya analizado correctamente la declaración.

Con Oracle como ejemplo, seguramente obtendría un error si lo hiciera:

select * from non_existant_table;

En este caso, "ORA-00942: tabla o vista no existe".

Sin embargo, si ejecutas:

select * frm non_existant_table;

Luego obtendrá un error de sintaxis, "ORA-00923: palabra clave FROM no encontrada donde se esperaba".

Debería ser posible clasificar los errores en los errores de análisis de sintaxis que indican una sintaxis incorrecta y errores relacionados con el nombre y los permisos de las tablas, etc.

Agregue a eso el problema de diferentes RDBMS e incluso versiones diferentes que permiten diferentes sintaxis y creo que realmente tiene que ir al motor de db para esta tarea.


Para validar las consultas, simplemente ejecútelas con SET NOEXEC ON , así es como lo hace Entreprise Manager cuando analiza una consulta sin ejecutarla.

Además, si está utilizando regex para validar consultas SQL, puede estar casi seguro de que perderá algunos casos de esquina, o que la consulta no es válida por otros motivos, incluso si es sintácticamente correcto.


Por lo que yo sé, esto va más allá de la expresión regular y su acercamiento a las artes oscuras de BnF y compiladores.

http://savage.net.au/SQL/

Lo mismo le sucede a las personas que quieren hacer un resaltado correcto de la sintaxis. Empiezas a meter cosas en expresiones regulares y luego terminas escribiendo un compilador ...


SQL es una gramática de tipo 2 , es demasiado poderosa para ser descrita por expresiones regulares. Es lo mismo que si decidiera generar código C # y luego validarlo sin invocar un compilador. El motor de base de datos, en general, es demasiado complejo para ser anulado fácilmente.

Dicho esto, puedes probar las gramáticas SQL de ANTLR .


Sugiero crear una base de datos con el mismo esquema, posiblemente usando un motor sql incorporado, y pasar el sql a eso.


Supongo que hizo algo así como ". *" Intente en su lugar "[^"] * "que le impedirá comer toda la línea. Todavía dará falsos positivos en casos en los que tenga /" dentro de sus cadenas.


Hay gramáticas ANTLR para analizar SQL. Realmente es una mejor idea usar una base de datos en memoria o una base de datos muy liviana como sqlite . Me parece un desperdicio comprobar si el SQL es válido desde el punto de vista del análisis, y mucho más útil para verificar los nombres de tabla y columna y los detalles de su consulta.


Tuve el mismo problema: un enfoque que funcionaría para todas las sentencias sql estándar sería crear una base de datos Sqlite en memoria y emitir la consulta en su contra, si obtiene un error "la tabla no existe", entonces su consulta analizada correctamente.


Las expresiones regulares pueden hacer coincidir idiomas, solo un autómata de estado finito puede analizar, lo cual es muy limitado, mientras que SQL es una sintaxis. Se puede demostrar que no se puede validar SQL con una expresión regular. Entonces, puedes dejar de intentarlo.


public bool IsValid(string sql) { string pattern = @"SELECT/s.*FROM/s.*WHERE/s.*"; Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase); return rgx.IsMatch(sql); }