miércoles, 10 de abril de 2019

MS Access - Run-time error 3000 - Reserved error (-7711) - SQL Server

Recientemente me he encontrado con este error es MS Access:

MS Access - Run-time error '3000' - Reserved error (-7171), there is no message for this error



Una posible causa a este problema puede ser el espacio de la base de datos. En mi caso, había llegado a la restricción de SQL Server Express. El detalle del error podía verse en el visor de sucesos de Windows:

CREATE DATABASE or ALTER DATABASE failed because the resulting cumulative database size would exceed your licensed limit of 10240 MB per database.

Algunas opciones para hacer espacio:

Log de transacciones

USE mibase
GO
ALTER DATABASE mibase
SET RECOVERY SIMPLE;
GO
DBCC SHRINKFILE ( mibase  _log, 1);
GO
ALTER DATABASE mibase
SET RECOVERY FULL;

Revisar espacio en MSDB

sp_helpdb msdb 



La siguiente consulta nos puede ayudar con el tamaño de las tablas.

select
    object_name(i.object_id) as ObjectName,
    i.[name] as IndexName,
    sum(a.total_pages) as TotalPages,
    sum(a.used_pages) as UsedPages,
    sum(a.data_pages) as DataPages,
    (sum(a.total_pages) * 8) / 1024 as TotalSpaceMB,
    (sum(a.used_pages) * 8) / 1024 as UsedSpaceMB, 
    (sum(a.data_pages) * 8) / 1024 as DataSpaceMB
from
    sys.indexes i
    inner join sys.partitions p 
        on i.object_id = p.object_id and i.index_id = p.index_id
    inner join sys.allocation_units a
        on p.partition_id = a.container_id
group by
    i.object_id, 
    i.index_id, 
    i.[name]
order by
    sum(a.total_pages) desc, 
    object_name(i.object_id)
go



Si el problema es de DataBase Mail, se pueden usar estos procedimientos (no usar truncate):

EXECUTE msdb.dbo.sysmail_delete_mailitems_sp @sent_before = 'October 9, 2005' ; GO 

EXECUTE msdb.dbo.sysmail_delete_log_sp  @logged_before = 'October 9, 2005' ;  
GO 

Usar con cuidado si tenemos muchos elementos para eliminar. Jugar con los rangos de fechas.
Es posible que se requiera posteriormente hacer un Shrink:



viernes, 29 de marzo de 2019

sp_send_dbmail - Attachment File is invalid

Cuando ejecutamos dbo.sp_send_dbmail dentro de un bloque de control de errores, observamos que el siguiente error no es capturado dentro del CATCH:

Msg 22051, Level 16, State 1, Line 0
Attachment file C:\test.xls is invalid.  

Una posible solución a este problema es controlar la existencia de los archivos antes de enviar el correo con xp_fileexist 

Ejemplo de código:

DECLARE @Attachments VARCHAR(MAX)
DECLARE @Attachment VARCHAR(8000)
DECLARE @AttachmentValid INT
DECLARE @DetailError VARCHAR(MAX)

SET @Attachments = 'a;sdf;32;34;3434'
SET @DetailError = ''

WHILE len(@Attachments) > 0
BEGIN
     SET @Attachment = left(@Attachments, charindex(';', @Attachments+';')-1)
     EXEC master.dbo.xp_fileexist @Attachment, @AttachmentValid OUTPUT  
     IF @AttachmentValid = 0 SET @DetailError = @DetailError + '[' + @Attachment + '] no es válido. '
     SET @Attachments = stuff(@Attachments, 1, charindex(';', @Attachments+';'), '')
END

viernes, 6 de enero de 2017

MS Access: The expression On Current you entered as the event property setting produced the following error

En caso de obtener el siguiente error:

"The expression On Current you entered as the event property setting produced the following error"



Pueden intentar resolverlo utilizando:

"C:\Program Files\Microsoft Office\Office14\MSACCESS.EXE" /decompile 

lunes, 31 de octubre de 2016

MS Access: Cannot perform join, group, sort, or indexed restriction. A value being searched or sorted on is too long

Me he encontrado con este problema en Access:

Cannot perform join, group, sort, or indexed restriction. A value being searched or sorted on is too long.



Si bien las causas pueden ser varias, en mi caso el problema fue vincular una tabla de SQL Server y seleccionar como clave primaria un campo que poseía valores mayores a 255 caracteres.

jueves, 27 de octubre de 2016

¿Cómo pasar un argumento al abrir un formulario en MSAccess?

El último argumento al abrir un formulario permite pasar parámetros:

    DoCmd.OpenForm "Certificados_Revision", acNormal, , , , , "M"

Luego en la apertura del formulario:

Private Sub Form_Open(Cancel As Integer)

    If Me.OpenArgs = "M" Then
        MsgBox Me.OpenArgs
    Else

viernes, 21 de octubre de 2016

SQL Server - Cannot resolve the collation conflict between

Al intentar crear una vista, se obtiene el siguiente error:

Msg 468, Level 16, State 9, Procedure V_Monitor_Emails_Detalle, Line 3
Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Modern_Spanish_CI_AS" in the UNION operation.

Contexto:
  • La vista es UNION entre una tabla y una vista
  • La tabla ha sido creada por el usuario
  • La vista es una vista sobre otra vista nativa de SQL Server
El problema es que algunas columnas tienen distintas "collation" que otras y esto es verificado por SQL Server, por cada columna al momento de hacer la UNION. En este caso la causa del problema es que una es una vista nativa y la otra es una tabla creada por el usuario.

Accediendo a las propiedades de cada columna, se puede ver el detalle:



La forma de resolverlo es agregando COLLATE DATABASE_DEFAULT en las columnas que correspondan, por ejemplo:

(...)

      ,[Enviado]
      ,[Error]
      ,[Cuenta]
FROM 
Correos C
UNION
SELECT Year(Fecha) As Anio, Month(Fecha) AS Mes, Day(Fecha) AS Dia, DATEPART(HOUR,Fecha) AS Hora,
      null AS [ID]
      ,null AS [Estado]
      ,null AS [Reintentos]
      ,null AS [Último reintento]
      ,[Fecha]
      ,'ND' AS [Para]
      ,null AS [CC]
      ,null AS [CO]
      ,Titulo COLLATE DATABASE_DEFAULT AS [Asunto]
      ,Adicional COLLATE DATABASE_DEFAULT AS [Cuerpo] 
      ,null AS [Adjuntos]
      ,null AS [Formato]

jueves, 20 de octubre de 2016

¿Cómo ejecutar un Stored Procedure de SQL Server desde MS Access que retorne un valor STRING?

Anteriormente explicamos cómo ejecutar un procedimiento de SQL Server. Pueden consultarlo en este enlace:


En esta oportunidad explicaremos cómo ejecutar un procedimiento que retorne un valor como el siguiente:

CREATE PROCEDURE dbo.CerrarProceso 
@proceso INT
AS
    SELECT 'resultado'
GO

La forma de ejecutar el procedimiento desde SQL sería:

EXECUTE CerrarProceso 286

La forma de ejecutarlo desde MS Access sería:

    Dim qdef As DAO.QueryDef
    Dim rs As Recordset
    Set qdef = CurrentDb.CreateQueryDef("")
    qdef.ReturnsRecords = True
    qdef.Connect = CurrentDb.TableDefs("[dbo_Estados]").Connect
    Dim sql As String
    sql = "EXEC CerrarProceso " & Proceso
    qdef.sql = sql
    Set rs = qdef.OpenRecordset()
    MsgBox (rs.Fields(0))