none
Problema al insertar en ACCESS 2007 desde VB 2008 Express RRS feed

  • Pregunta

  • Me he encontrado con un posible bug y quisiera vuestra opinión.

    Tengo una tabla definida en ACCESS 2007 con una columna que tiene la siguiente regla de validación )like "CM*") para uno de sus campos.

    Verifico desde el gestor de tablas de access su correcto funcionamiento.

    Desde un programa en visualbasic 2008 Express hago el siguiente insert

    dim SQLtxt as string

    dim cmd as Oledbcommand

    VIDMAQUINA="CM29"

    VDESCMAQUINA="DAIGUAL"

    SQLtxt="Insert into maquinas (idmaquina,descmaquina) values (' " & VIDMAQUINA & " ',' " & VDESCMAQUINA & " ') "

    cmd=new oledbcommand(sqltxt,cnn)

    cmd.executeNonQuery()

    Si ejecuto la instrucción me falla saltando por una excepción que indica que el problema es que la regla de validación para el campo idmaquina falla.

    1. Si quito la regla de validación (like CM* ) de la columna idmaquina la sentencia insert funciona correctamente desde el programa vb.net

    2. Si, dejando la regla definida, pongo un break point en modo debug para ver el valor de la variable SQLtxt y a continuación hago un copy paste para crear una consulta en ACCESS y probar, el resultado es que la sentencia se ha construido bien porque se inserta sin problemas.

    3. Si borro la regla de validación y ejecuto el programa vb.net que hace el insert los datos se graban correctamente. Y si a continuación creo la regla sobre los datos grabados (desde ACCESS) la regla se crea sin problemas  indicando que los datos han entrado de forma correcta.

    ¿Alguien se ha encontrado con este problema?

    Gracias

     

    martes, 5 de abril de 2011 12:11

Respuestas

  • "Noferatur" escribió:

    > Veo que para ti lo más importante es el programa vb y
    > para mi la integridad de la base de datos a cualquier
    > costa (incluso de los programadores que accedan a ella).

    Como programador de aplicaciones con Visual Basic, lo importante para mí es tanto el programa como el diseño de la base de datos. ¿Que los valores de un campo de una tabla necesitan que comiencen por las letras CM? Antes de enviar los datos a la base de datos, compruebo que así sea. Si no cumple el requisito, se lo indico al usuario y no envío los datos. ¿Que cumplen todos los requisitos? Envío los datos a la base de datos.

    ¿Que tu deseas añadir reglas de validación a nivel de los campos? Me parece estupendo, me imagino que será porque tu aplicación la utiliza tanto cualquier usuario que la abre con Microsoft Access como con una aplicación de Visual Basic.

    Pero en fin, de nada sirve discutir sobre lo conveniente o no de utilizar reglas de validación a nivel de campo, porque como dicen por ahí «para gustos están los colores».

    > OK. Voy a dar por terminado este hilo.
    >
    > De verdad, muchas gracias por tu tiempo y tu ayuda
    > que ha sido muy didáctica

    De nada, me alegro que mis explicaciones te hayan servido de ayuda. Pero si alguna respuesta te ha servido para solucionar el tema de la regla de validación, lo correcto es que des por finalizada la conversación marcando como satisfactoria la respuesta o respuestas que te hayan sido útiles. Por supuesto si así lo crees conveniente, claro está. :-)

     

     


    Enrique Martínez
      [MS MVP - VB]



    • Marcado como respuesta Noferatur jueves, 7 de abril de 2011 12:54
    jueves, 7 de abril de 2011 10:01
    Moderador

Todas las respuestas

  • hola

    1-

    pero esta calidacion que usa el LIKE CM* esta en tu codigo .net o dentro de la propio Access, porque si falla entonces quiere decir que esta query que ahces es la del problema

    2 -

    podrias poner como construyes esta consulta ?

    3 -

    esto claramente indica que el problema entonces esta en el sql que usa el LIKE en la consulta

     

    algo que recomendaria es que uses parametros, o sea sua algo como esto

     

    Dim VIDMAQUINA As String ="CM29"

    Dim VDESCMAQUINA As String ="DAIGUAL"

    Dim SQLtxt as string = "Insert into maquinas (idmaquina,descmaquina) values (@id, @desc) "

    Dim cmd as New Oledbcommand(sqltxt,cnn)
    cmd.Parameters.AddWithValue("@id",  VIDMAQUINA)
    cmd.Parameters.AddWithValue("@desc",  VDESCMAQUINA)

    cmd.executeNonQuery()

     

    y en la query del LIKE tambien, veras alli que no se concatenas el string para realizar la consulta

     

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    martes, 5 de abril de 2011 12:25
  • "Noferatur" escribió:

    > Me he encontrado con un posible bug y quisiera vuestra opinión.
    >
    > Tengo una tabla definida en ACCESS 2007 con una columna que tiene
    > la siguiente regla de validación )like "CM*") para uno de sus campos.
    >
    > VIDMAQUINA="CM29"
    > Si ejecuto la instrucción me falla saltando por una excepción que
    > indica que el problema es que la regla de validación para el campo
    > idmaquina falla.

    Pues lo único que te puedo decir que NO ES UN BUG, más bien un "bug tuyo". :-)

    Si el campo tiene la regla de validación CM*, ese será el único valor que puede tener el campo. Pero si tu quieres que el valor solamente comience por las letras CM, entonces la regla de validación deberá ser

      Like "CM%"

    Es decir, en lugar de utilizar el carácter *, deberás de utilizar el carácter %.

    De todas maneras, como en otra conversación has preguntado cómo eliminar la regla de validación, lo mismo ésta explicación ya no te hace falta. :-)

     


    Enrique Martínez
      [MS MVP - VB]

    martes, 5 de abril de 2011 14:10
    Moderador
  • Creo Leandro que no recuerdas como se hacen las restricciones a nivel de campo o columna en una tabla Access.

    El like CM* no forma parte de ninguna sentencia SQL que yo construya sino que al definir la tabla en ACCESS en la pestaña GENERAL de propiedades del campo se puede definir una regla de validación para ese campo.

    Si el ACCESS está en español lo que se ve en esta pestaña es

    Regla de validación     Como "CM*" (esto es lo que yo introduzco)

    Te aseguro que el problema no está en la construcción de la sentencia, ya que como he indicado en mi pregunta ,si hago un break en debug justo en el momento de tener construida la sentencia en una variable y visualizo y capturo el valor de esta variable y la ejecuto desde el constructor de sentencias de ACCESS, funciona correctamente (la sintaxis es correcta).

    Por otra parte, he probado la forma que me indicas de hacer la consulta (pasando parámetros) y se produce el mismo error. E incluso he probado a escribir toda la consulta como una constante para restringuir que fuera un problema de la confección de la misma.

    El mensaje de error que se obtiene es Insert failed uno o más de los valores están prohibidos por la regla de validación 'like "CM*"' establecida para la tabla maquinas.

    He probado con otra tabla sencilla en que el campo era numerico y tenía una regla de validación >200 y funciona correctamente. El problema parece estar relacionado con la utilizacion del LIKE , o lo que es lo mismo, del COMO en la versión es español porque cuando en esta version escribes LIKE en el texto de la regla de validación, ACCESS automaticamente te lo cambia por un LIKE.

    Las pruebas las ha realizado con ACCESS 2007 y VisualBasic 2008 Express.

    Saludos

     

    martes, 5 de abril de 2011 14:15
  • > Regla de validación     Como "CM*" (esto es lo que yo introduzco)

    Ignoro si has leído mi anterior mensaje, pero insisto que, si esa es la regla de validación que has especificado en el campo, con el signo *, entiendo que no puedes introducir el valor CM29, de ahí el error que obtienes:

         Insert failed uno o más de los valores están prohibidos
         por la regla de validación 'like "CM*"' establecida para
         la tabla maquinas.

    Modifica el signo por el %, y entonces sí podrás introducir el mencionado valor.


    Enrique Martínez
      [MS MVP - VB]


    martes, 5 de abril de 2011 15:48
    Moderador
  • Tienes razón no había leido tu mensaje.

    Anteriormente había preguntado como eliminar la regla porque veo que no encuentro la raiz del problema. Y para un caso en concreto, a la desesperada ,voy a eliminar la regla porque tengo que entregar al cliente una solución sin más demora. Sin embargo, esto no quiere decir que no quiera encontrar el motivo del problema.

    ¿Has probado a definir una tabla con un campo en ACCESS con la regla de validación que me plantea problemas tal y como tu dices?. Porque te puedo aseguar que la regla se escribe con * y no con %. Pero como siempre estoy abierto a otras posiblidades he definido la regla con un CM% tal y como me expones y el resultado es que ACCESS de esta forma no me admite el valor CM29 mientras que con CM* si me lo admite. Utilizo ACCESS 2007 en español

    He introducido esta pregunta en el foro de ADO.net por si alguna otra persona podía sugerirme que es lo que ocurre o por si se hubiera encontrado con este problema pero veo que Leandro Tuttini ha decidido cerrar la pregunta porque la da como contestada en este hilo. En fin, gracias por vuestro tiempo.

    miércoles, 6 de abril de 2011 6:31
  • > ¿Has probado a definir una tabla con un campo en ACCESS
    > con la regla de validación que me plantea problemas tal
    > y como tu dices?

    Sí, en una base de datos versión Access 2007, diseñada con Microsoft Access 2007 en español.

    > Porque te puedo aseguar que la regla se escribe con * y no con %.

    Pues no puedo decir lo mismo. Si escribo la siguiente regla de validación:

       ALike "CM*"

    Solamente puedo escribir el valor CM* en dicha columna. En cambio, si la regla de validación es

       ALike "CM%"  

    entonces sí puedo escribir los siguientes valores:

       CM29
       CM89
       CM45
       CM98

    Una vez que tengas las base de datos de Access abierta en el IDE de Microsoft Access, entra en las propiedades de Access, seleccionas la pestaña «Diseñadores de objetos», y mira si tienes o no activada la siguiente opción:

      Sintaxis compatible con SQL Server (ANSI 92)
          Esta base de datos 

    Mira si está o no activada la casilla de verificación correspondiente a «Esta base de datos».

    Creo recordar que la versión de tu base de datos es de Access 2003. ¿Correcto?

    > He introducido esta pregunta en el foro de ADO.net por
    > si alguna otra persona podía sugerirme que es lo que
    > ocurre o por si se hubiera encontrado con este problema
    > pero veo que Leandro Tuttini ha decidido cerrar la
    > pregunta porque la da como contestada en este hilo.

    Efectivamente, así es. Lo que te está diciendo Leandro Tuttini es que continúes la conversación en éste foro, y no abras más conversaciones, en éste o en otro foro, para la misma pregunta. Ten en cuenta que los que participamos en éste foro, también lo hacemos en el foro de ADO .NET.

     


    Enrique Martínez
      [MS MVP -

    miércoles, 6 de abril de 2011 11:22
    Moderador
  • Vale. Acepto pulpo como animal de compañia.

    Tienes razón. Si defino la base de datos para que utilice sintaxis ANSI 92 se modifican los caracteres cómodines como * y ? que pasan a ser % y _ respectivamente. Y con la base de datos de esta forma el insert desde vb.net funciona correctamente.

    Esto explica el misterio de que yo pudiera meter el caracter * como comodín. Esto y el darme cuenta que a pesar de utilizar ACCESS 2007 estaba abriendo una base de datos que tiene formato ACCESS 2003.

    Hasta ahora nunca había marcado ninguna base de datos para utilizar el standard ANSI92 porque por defecto al crearla siempre están sin desmarcadas.

    Todo esto hace que evidentemente no se pueda hablar de un bug.

    ¿Se trata de una restricción de vb2008 al acceder a una base de datos ACCESS 2003 con formato  ANSI 89?. ¿Sólo acepta la sintaxis de ANSI 92?

    Estoy accediendo con este string

    OleDbConnection ("Provider=Microsoft.Jet.OLEDB.4.0;Data source=......

    ¿Hay alguna forma de indicarle en el programa vb.net que acepte la sintaxis ANSI 89 sin tener que cambiar nada de ACCESS?

    No creas que quiero complicarme la vida por gusto es que el programa vb.net debe ser ejecutado en varios ordenadores de mi cliente en modo desasistido y el formato de base de datos que tiene es ACCESS 2003 notación ANSI 89.

    No quiero decirle (a no ser que sea por imperativo externo) que tiene que cambiar en todas sus bases de datos (una por oficina) el tipo de sintaxis ANSI y que además esto puede afectar a las consultas que el tenga diseñadas.

    Gracias

     

    miércoles, 6 de abril de 2011 15:14
  • "Noferatur" preguntó:

    > Estoy accediendo con este string
    >
    > OleDbConnection ("Provider=Microsoft.Jet.OLEDB.4.0;Data source=......
    >
    > ¿Hay alguna forma de indicarle en el programa vb.net que acepte
    > la sintaxis ANSI 89 sin tener que cambiar nada de ACCESS?

    Para tu tranquilidad te diré que, mientras que estés utilizando la versión 4.0 del proveedor de datos OleDb Microsoft Jet desde tu aplicación de Visual Basic .NET, estarás usando el modo ANSI SQL-92, por tanto, no tienes que hacer ningún cambio en las propiedades de tu base de Access 2003. Bueno, sí tienes que cambiar el carácter comodín de la regla de validación del campo, si deseas continuar con dicha regla de validación, cuestión ésta que en otro mensaje ya te indiqué cómo tienes que hacerlo. En lugar de eliminar la regla de validación, cambia la regla.

    De todas maneras, acabo de realizar una nueva prueba, y aunque elimine de la base de Access 2003 la sintaxis compatible con SQL Server (ANSI 92), no puedo introducir datos si la regla de validación lleva el asterisco: ALike "CM*".

    Por narices tengo que cambiar el signo por el % para que pueda utilizarlo como comodín, lo que me lleva a pensar que no tiene nada que ver con la sintaxis de ANSI 92. ¿?

    Lo mismo te son útiles los siguientes enlaces que pertenecen a la ayuda de Microsoft Office Access 2003:

    Los proyectos y páginas de acceso a datos de Access usan ahora la sintaxis ANSI SQL-92

    Comparación entre Microsoft Jet SQL y ANSI SQL

    Como le indiqué ayer a Leandro Tuttini, yo no soy muy partidario de establecer reglas de validación a los campos de una tabla, porque si la base de datos únicamente va a interactuar con una aplicación, desarrollada en cualquier lenguaje de programación, las validaciones las tengo que hacer en la propia aplicación. ¿Para que "leches" quiero enviar unos datos a la base de datos, para que ésta no los admita y me los rechaze? Pienso que es un viaje tonto el mandar unos datos no válidos a la base de datos y que ésta me devuelva una excepción o error. Como decía un actor cómico en televisión, ¡si hay que ir se va, pero ir pa ná, es tontería! :-))

    Para los programadores de bases de datos de Access, o aquellos que trabajan con la base de datos desde la propia interfaz de usuario de Microsoft Access, quizás pueda tener sentido establecer esas reglas de validación, pero para un programador de Visual Basic, C#, o de cualquier otro lenguaje de programación, yo no lo encuentro sentido alguno. ¡Que me lo expliquen! :-)

    Tienes que diseñar las tablas y consultas, así como las relaciones entre ellas, y no entrar en detalles de los campos de la tabla, salvo en el tipo de dato, su longitud, si es o no requerido, si deseas que admita o no valores NULL, o si deseas que tenga un valor predeterminado, pero ¿una regla de validación?

    Es como si te dedicaras a diseñar un formulario en la propia base de Access. ¿Para qué quieres ese formulario, si los usuarios de tu aplicación, ni siquiera lo van a ver? Los usuarios de tu aplicación van a ver otros formularios muy distintos. :-)

     


    Enrique Martínez
      [MS MVP - V

    miércoles, 6 de abril de 2011 21:41
    Moderador
  • OK. Voy a dar por terminado este hilo.

    No veo que lleve a ninguna parte seguir intercambiando opiniones sobre como se diseña una base de datos pero discrepo de tu criterio. Veo que para ti lo más importante es el programa vb y para mi la integridad de la base de datos a cualquier costa (incluso de los programadores que accedan a ella). Y con respecto a que no te deje poner el * al definir la regla de validación no lo entiendo. Tengo en la empresa varios ordernadores con XP y WIN7 y ACCESS2003 y ACCESS2007 y en todos puedo hacerlo así.  Está claro que a partir de ahora emplearé siempre la notación ANSI SQL-92 para evitar problemas en el futuro.

    De verdad, muchas gracias por tu tiempo y tu ayuda que ha sido muy didáctica

    Saludos

    jueves, 7 de abril de 2011 7:51
  • "Noferatur" escribió:

    > Veo que para ti lo más importante es el programa vb y
    > para mi la integridad de la base de datos a cualquier
    > costa (incluso de los programadores que accedan a ella).

    Como programador de aplicaciones con Visual Basic, lo importante para mí es tanto el programa como el diseño de la base de datos. ¿Que los valores de un campo de una tabla necesitan que comiencen por las letras CM? Antes de enviar los datos a la base de datos, compruebo que así sea. Si no cumple el requisito, se lo indico al usuario y no envío los datos. ¿Que cumplen todos los requisitos? Envío los datos a la base de datos.

    ¿Que tu deseas añadir reglas de validación a nivel de los campos? Me parece estupendo, me imagino que será porque tu aplicación la utiliza tanto cualquier usuario que la abre con Microsoft Access como con una aplicación de Visual Basic.

    Pero en fin, de nada sirve discutir sobre lo conveniente o no de utilizar reglas de validación a nivel de campo, porque como dicen por ahí «para gustos están los colores».

    > OK. Voy a dar por terminado este hilo.
    >
    > De verdad, muchas gracias por tu tiempo y tu ayuda
    > que ha sido muy didáctica

    De nada, me alegro que mis explicaciones te hayan servido de ayuda. Pero si alguna respuesta te ha servido para solucionar el tema de la regla de validación, lo correcto es que des por finalizada la conversación marcando como satisfactoria la respuesta o respuestas que te hayan sido útiles. Por supuesto si así lo crees conveniente, claro está. :-)

     

     


    Enrique Martínez
      [MS MVP - VB]



    • Marcado como respuesta Noferatur jueves, 7 de abril de 2011 12:54
    jueves, 7 de abril de 2011 10:01
    Moderador
  • Ok. Voy a marca como respuesta pero antes expongo lo que acabo de averiguar y que me va a solucionar el problema por si a alguien le necesita.

    1) He averiguado que en ACCESS 2003 se puede utilizar Alike (no lo sabía) porque yo lo que siempre utilizaba hasta ahora era like (sin la A inicial). Pensaba que Alike era nuevo en ACCESS 2007.

    En ACCESS2003 sin indicarle explicitamente que utilice la notación SQLServer, es igual de válido definir una regla de validación utilizando LIKE "CM*" (el access en español lo traduce automaticamente a COMO "CM*") como utilizar ALIKE "CM%". 

    2) Cuando se accede a una base de datos ACCESS  desde VB.bet con ADO (OLEDB) se utiliza la nomenclatura ANSI 92. Por eso es que falla con una regla de validación que está definida en notación ANSI 89.

      Si en cambio, desde vb.net agregamos la referencia a DAO y utilizamos esta forma de acceso las sentencias si admiten la nomenclatura ANSI 89.

    La sentencia insert que iba contra una tabla ACCESS2003 con una columna restringuida por una regla de la forma like "CM*" fallaba cuando el acceso lo hacia de la siguiente forma:

    ....

    SQLTXT="Insert into tabla (campo1) values ('CM29') "

    cnn=OleDbConnection ("Provider=Microsoft.Jet.OLEDB.4.0;Data source=FicheroMDB2003)

    cmd=new(oledbcommand,SQLtxt,cnn)

    cmd.excutenonquery()

    ....

    y en cambio si funciona si el acceso lo hago con la referencia a DAO (para lo que tengo que referenciar la libreria Microsoft DAO 3.6 Object Library l)

    ....

    dim dbe as dao.dbengine

    dim db as dao.database

    dbe=new dao.dbengine

    db=dbe.opendatabase (FicheroMDB2003)

    db.execute(SQLTXT)

    ....

     

    Ya tengo el problema resuelto.

     

    jueves, 7 de abril de 2011 12:53
  • "Noferatur" escribió:

    > y en cambio si funciona si el acceso lo hago con la referencia a DAO
    > (para lo que tengo que referenciar la libreria Microsoft DAO 3.6
    > Object Library l)
    >
    > Ya tengo el problema resuelto.

    No me digas que vas a utilizar la biblioteca COM de DAO 3.6, desde tu aplicación de Visual Basic .NET, para interactuar con tu base de Access. Por si lo ignoras, te comento que esa biblioteca hace ya bastante tiempo que se declaró como una tecnología de acceso a datos "obsoleta", tal y como así se explica en el siguiente artículo de MSDN:

    Data Access Technologies Road Map

    Lee bien el apartado «Obsolete Data Access Technologies». :-)

    Como comprenderás, puedes hacer lo que creas conveniente, pero desde luego, te vas a perder todos los beneficios que otorga trabajar con el proveedor de datos OleDb para Microsoft Jet (proveedor éste que últimamente también está en declive y que está siendo sustituido por el proveedor de datos OleDb para Microsoft ACE), lo que quiere decir que no vas a poder trabajar desde tu aplicación .NET con el proveedor de datos .NET para Ole Db, es decir, las clases contenidas en el espacio de nombres System.Data.OleDb.

    Efectivamente, la biblioteca de DAO trabaja con ANSI SQL-89 al igual que el propio Microsoft Access, salvo que le indiques expresamente en las opciones de Microsoft Access, que deseas que la base de datos de Access 2003 utilice ANSI SQL-92, tal y como así te indiqué.

    En fin, tú verás lo que haces. :-)


    Enrique Martínez
      [MS MVP - VB]

    jueves, 7 de abril de 2011 18:22
    Moderador