Tengo montado un sistema cliente/servidor de bases de datos y aplicaciones Access. He migrado las tablas a SQL Server para mejorar el rendimiento (vinculándolas vía ODBC), pero me he encontrado con el problema siguiente: Cuando se producen advertencias en las aplicaciones (campos obligatorios, etc), además de los mensajes Access se muestran los mensajes generados por SQL Server que son bastante extraños para los usuarios (parecen errores graves en lugar de advertencias). ¿Cómo puedo interceptar y/o eliminar estos mensajes?.
En vez de eliminar los mensajes de advertencias de sql server yo trataría de manejarlos, es decir un mensaje se produce por que algo fallo o puede fallar, la idea seria evitar que esto pasara, es decir validar todo antes de enviar la orden al servidor.
Entiendo, pero manejar todos los fallos posibles en 35-40 aplicaciones es un trabajo enorme. Pensaba en la posibilidad de configurar la base de datos SQL Server para que no emita ciertos mensajes. ¿Existe algo parecido?
No conozco ninguno
- Anónimoahora mismo
Respuesta de santiagomf
1
1
santiagomf, Más de 35 años en la informática y más de 20 trabajando con...
Supongo que se tratará de mensajes tipo 'clave duplicada' o algo así. Ahora estoy en casa y no tengo ningún Sql Server a mano, pero si lo que se me ocurre de momento no te sirve, dímelo y mañana hago pruebas en mi trabajo (allí tengo ambos gestores). En principio lo que haría es quitar todos los mensajes de error durante la operación y controlaría yo los mensajes: on error resume next docmd.runsql "insert into................." if err<>0 then ' Hay un error msgbox "Error al insertar el registro. Mensaje del sistema:" & vbcrlf & error$ end if on error goto 0 Si con esto te siguen apareciendo, prueba a quitar los avisos de Access (ademas de controlar tu los errores). Los mensajes de aviso se quitan y ponen con: docmd. setwarnings = false o true. Espero que te funcione. Si no, dímelo y mañana lo miro.
"On error resume next" ya lo había probado y "docmd.setwarnings = false" acabo de comprobar que no funciona. Pero ya que estaba puesto se me han ocurrido un par de cosas y me han dado una idea de por dónde puede ir la cosa. Parece que el mensaje de error de SQL Server se produce básicamente cuando la clave principal es null, y esta validación es la última que se realiza. Si Access encuentra un error anterior sólo se muestra el mensaje de error Access. Así pues, la solución al problema consiste en controlar las claves de las tablas y ésto no lo veo fácil, al menos de una forma sencilla y estándar. Haz unas pruebas sobre ésto a ver si encuentras la forma.
Entonces controla tú primero que la clave no sea nula ni que exista previamente. El control del nulo lo puedes hacer con una instrucción "if isnull(<campo>) then...". Para saber si existe la clave antes de insertar puedes hacer una consulta de selección previa y si te devuelve algún registro significa que ya existe. Podrías crearte una función de este estilo: Function snOkInsertarClave(ByVal nomTbl As String, _ ByVal nomCampoClave1 As String, ByVal valorClave1 As Variant, _ Optional nomCampoClave2 As String = "", Optional valorClave2 As Variant = Null, _ Optional nomCampoClave3 As String = "", Optional valorClave3 As Variant = Null, _ Optional nomCampoClave4 As String = "", Optional valorClave4 As Variant = Null) As Boolean Dim rs As Recordset Dim aux As String Dim txtSql As String snOkInsertarClave = False ' Comprobamos que no se vaya a insertar un valor nulo en la clave ' Si nos indican un nombre para el campo 2, 3 o 4, también sus valores tienen que ' ser no nulos If IsNull(valorClave1) Or _ (NomCampoClave2 <> "" And IsNull(valorClave2)) Or _ (NomCampoClave3 <> "" And IsNull(valorClave3)) Or _ (NomCampoClave4 <> "" And IsNull(valorClave4)) Then MsgBox "Los campos que forman la clave no pueden ser nulos" Exit Function End If ' Ya sabemos que los valores no son nulos ' Construimos un SQL para la clausula WHERE usada con las claves aux = miraFormatoComparacion(nomTbl, nomCampoClave1, valorClave1) If aux = "" Then Exit Function ' Ha habido un error txtSql = "WHERE (" & aux & ")" If nomCampoClave2 <> "" Then ' La clave tiene un segundo campo aux = miraFormatoComparacion(nomTbl, nomCampoClave2, valorClave2) If aux = "" Then Exit Function ' Ha habido un error txtSql = txtSql & " and (" & aux & ")" End If If nomCampoClave3 <> "" Then ' Y un tercero aux = miraFormatoComparacion(nomTbl, nomCampoClave3, valorClave3) If aux = "" Then Exit Function ' Ha habido un error txtSql = txtSql & " and (" & aux & ")" End If If nomCampoClave4 <> "" Then ' Y un cuarto aux = miraFormatoComparacion(nomTbl, nomCampoClave4, valorClave4) If aux = "" Then Exit Function ' Ha habido un error txtSql = txtSql & " and (" & aux & ")" End If ' Abrimos la consulta para ver si existe la clave Set rs = CurrentDb().OpenRecordset(txtSql) snOkInsertarClave = rs.EOF ' Se puede insertar si no hay ningún registro rs.Close End Function Function miraFormatoComparacion(ByVal nomTbl As String, ByVal nomCampoClave As String, ByVal valorClave As Variant) As String Dim aux As String Dim tipoCampo As Long On Error Resume Next tipoCampo = CurrentDb().TableDefs(nomTbl).Fields(nomCampoClave).Type If Err <> 0 Then MsgBox "Error al localizar el tipo de datos del campo " & _ "'" & nomCampoClave & "' de la tabla '" & nomTbl On Error GoTo 0 Exit Function End If On Error GoTo 0 aux = "[" & nomCampoClave & "]=" Select Case tipoCampo Case dbText: aux = aux & "'" & valorClave & "'" Case dbDate: aux = aux & "dateserial(" & Format$(valorClave, "yyyy,mm,dd") & ")" Case dbBoolean: If valorClave Then aux = aux & "true" Else aux = aux & "false" Case dbInteger, dbLong, dbDecimal, dbDouble, dbSingle: aux = aux & Str$(valorClave) Case Else: MsgBox "Tipo de datos desconocido (" & tipoCampo & ") para el campo " & _ "'" & nomCampoClave & "' de la tabla '" & nomTbl Exit Function End Select miraFormatoComparacion = aux End Function Por cierto, al trabajar con Sql Server, es posible que tengas que cambiar la instrucción Case del final y poner, en lugar de valores 'db' sus correspondientes con 'ac' (en lugar de dbText usar acText). No estoy seguro de esto, pero por si acaso lo comento.