vba ms-access

vba - Obteniendo Error 3340 Query '''' está dañado al ejecutar consultas DoCmd.RunSQL



ms-access (10)

Desde que instalé la actualización de Windows para Office 2010 resolviendo KB 4484127 , recibo un error al ejecutar consultas que contienen una cláusula WHERE.

Por ejemplo, ejecutando esta consulta:

DoCmd.RunSQL "update users set uname= ''bob'' where usercode=1"

da como resultado este error:

Número de error = 3340 La consulta '''' está corrupta

La actualización en cuestión todavía está instalada actualmente:

¿Cómo puedo ejecutar con éxito mis consultas? ¿Debo desinstalar esta actualización?


La solución más simple

Para mis usuarios, esperar casi un mes hasta el 10 de diciembre para una versión de reparación de Microsoft no es una opción. Tampoco está desinstalando la actualización ofensiva de Microsoft en varias estaciones de trabajo bloqueadas por el gobierno.

Necesito aplicar una solución alternativa, pero no estoy exactamente entusiasmado con lo que sugirió Microsoft: crear y sustituir una consulta para cada tabla.

Lo siguiente funciona y no requiere crear y guardar una tonelada de consultas adicionales, ni ninguna tabla o función falsa.

Antes: ACTUALIZAR Table1 SET Field1 = "x" WHERE (Field2 = 1); ''Genera error

Después: ACTUALIZAR (SELECCIONAR * DE la Tabla1) SET Field1 = "x" WHERE (Field2 = 1); ''No hay error

Eso debería ser mucho más fácil de implementar en varias bases de datos y aplicaciones (y en una reversión posterior).


Este es un error conocido causado por las actualizaciones de Office lanzadas el 12 de noviembre de 2019. Afecta a todas las versiones de Access actualmente compatibles con Microsoft (desde Access 2010 hasta 365).

Los parches para este error se lanzarán pronto, aquí está la tabla de tiempos citada de la página oficial de Microsoft para este error :

  • Acceso 2010: 22 de noviembre de 2019 (estimado)
  • Acceso 2013: 22 de noviembre de 2019 (estimado)
  • Access 2016 MSI: parche disponible (KB4484198)
  • Acceda a la Licencia por Volumen 2019: 10 de diciembre de 2019
  • Access para Office 365 / Access 2016 C2R / Access 2019 (Versión 1911): parche disponible (use "Actualizar ahora")
  • Acceso para Office 365 semestral (1901): 25 de noviembre de 2019 (estimado)

Para las versiones donde todavía no se ha lanzado un parche, ayuda a desinstalar la actualización ofensiva (bajo su propio riesgo, obviamente, usted vuelve a abrir las vulnerabilidades de seguridad corregidas por la actualización ). Al final de esta publicación puede encontrar un archivo por lotes para ayudar con eso.

Aquí hay un ejemplo de reproducción mínima:

  1. Cree una nueva base de datos de Access.
  2. Cree una nueva tabla vacía "Tabla1" con el campo ID predeterminado y un campo Entero largo "myint".
  3. Ejecute el siguiente código en la ventana Inmediato del editor de VBA:

    CurrentDb.Execute "UPDATE Table1 SET myint = 1 WHERE myint = 1"

Resultado esperado : la declaración finaliza correctamente.

Resultado real con una de las actualizaciones de errores instaladas: se produce el error de tiempo de ejecución 3340 ("La consulta ''está dañada").

Actualmente distribuimos este archivo por lotes (¡se ejecuta como Administrador!) A nuestros clientes para desinstalar los parches problemáticos y / o revertir Office Click-to-Run a una buena versión conocida:

REM KB4484127 (Office 2010) reg query HKEY_LOCAL_MACHINE/SOFTWARE/WOW6432Node/Microsoft/Windows/CurrentVersion/Uninstall/{91140000-0011-0000-0000-0000000FF1CE} if %errorlevel% equ 0 ( "C:/Program Files (x86)/Common Files/Microsoft Shared/OFFICE14/Oarpmany.exe" /removereleaseinpatch "{91140000-0011-0000-0000-0000000FF1CE}" "{F11D3275-8FE0-4ADB-B737-9766F9D0AD5B}" "1031" "0" ) REM KB4484127 (Access 2010 Runtime) reg query HKEY_LOCAL_MACHINE/SOFTWARE/WOW6432Node/Microsoft/Windows/CurrentVersion/Uninstall/{90140000-001C-0000-0000-0000000FF1CE} if %errorlevel% equ 0 ( "C:/Program Files (x86)/Common Files/Microsoft Shared/OFFICE14/Oarpmany.exe" /removereleaseinpatch "{90140000-001C-0000-0000-0000000FF1CE}" "{F11D3275-8FE0-4ADB-B737-9766F9D0AD5B}" "1031" "0" ) REM KB4484119 (Office 2013) reg query HKEY_LOCAL_MACHINE/SOFTWARE/WOW6432Node/Microsoft/Windows/CurrentVersion/Uninstall/{90150000-006E-0407-0000-0000000FF1CE} if %errorlevel% equ 0 ( "C:/Program Files (x86)/Common Files/Microsoft Shared/OFFICE15/Oarpmany.exe" /removereleaseinpatch "{90150000-006E-0407-0000-0000000FF1CE}" "{3B7EE494-CBED-477C-AF90-8B8653C86985}" "1031" "0" ) REM KB4484119 (Access 2013 Runtime) reg query HKEY_LOCAL_MACHINE/SOFTWARE/WOW6432Node/Microsoft/Windows/CurrentVersion/Uninstall/{90150000-001C-0000-0000-0000000FF1CE} if %errorlevel% equ 0 ( "C:/Program Files (x86)/Common Files/Microsoft Shared/OFFICE15/Oarpmany.exe" /removereleaseinpatch "{90150000-001C-0000-0000-0000000FF1CE}" "{3B7EE494-CBED-477C-AF90-8B8653C86985}" "1031" "0" ) REM Office Click-to-Run if exist "C:/Program Files/Common Files/microsoft shared/ClickToRun/OfficeC2RClient.exe" ( "C:/Program Files/Common Files/microsoft shared/ClickToRun/OfficeC2RClient.exe" /update user updatetoversion=16.0.12130.20272 )

(Tenga en cuenta que este script actualmente no cubre las versiones de 64 bits, Office 2016 MSI o Access 2016 Runtime).

Enlaces relacionados:


Este no es un problema de actualización de Windows, sino un problema que se introdujo con la versión de noviembre de Patch Tuesday Office. Un cambio para corregir una vulnerabilidad de seguridad hace que algunas consultas legítimas se denuncien como corruptas. Debido a que el cambio fue una solución de seguridad, afecta TODAS las compilaciones de Office, incluidas 2010, 2013, 2016, 2019 y O365.

El error se ha corregido en todos los canales, pero el momento de la entrega dependerá de en qué canal se encuentre.

Para 2010, 2013 y 2016 MSI, y las compilaciones de licencias por volumen de 2019, y el canal semestral O365, la solución será en la versión Martes de parche de diciembre, 10 de diciembre. Para O365, Canal mensual e Insiders, esto se solucionará cuando se lanza la bifurcación de octubre, actualmente planificada para el 24 de noviembre.

Para el canal semianual, el error se introdujo en 11328.20468, que se lanzó el 12 de noviembre, pero no se implementa a todos a la vez. Si puede, es posible que desee retrasar la actualización hasta el 10 de diciembre.

El problema ocurre para las consultas de actualización en una sola tabla con un criterio especificado (por lo que otros tipos de consultas no deberían verse afectados, ni ninguna consulta que actualice todas las filas de una tabla, ni una consulta que actualice el conjunto de resultados de otra consulta). Dado eso, la solución más simple en la mayoría de los casos es cambiar la consulta de actualización para actualizar otra consulta que seleccione todo de la tabla, en lugar de actualizar la consulta directamente.

Es decir, si tiene una consulta como:

UPDATE Table1 SET Table1.Field1 = "x" WHERE ([Table1].[Field2]=1);

Luego, cree una nueva consulta (Consulta1) definida como:

Select * from Table1;

y actualice su consulta original a:

UPDATE Query1 SET Query1.Field1 = "x" WHERE ([Query1].[Field2]=1);

Página oficial: Error de acceso: "La consulta está dañada"


Gracias a @Gustav encontré una solución simple de trabajo.

Esta solución funciona perfectamente en cualquier consulta de actualización , no es necesario eliminar actualizaciones ni cambiar la versión de ms access.

Me han dado cuenta de que si hay unir en la consulta de actualización, ¡es un trabajo!

¡Solo cuando se actualiza una tabla se genera un error!

Por lo tanto, creo una nueva tabla con una fila y siempre las actualizo por ejemplo, esta consulta:

DoCmd.RunSQL "update users set uname= ''bob'' where usercode=1"

Se convertirá así:

DoCmd.RunSQL "update users,fixwindowsbugs set uname= ''bob'' where usercode=1"

Cualquier paso es importante:

  1. Agregue una nueva tabla llamada ''fixwindowsbugs'' con una columna llamada ''fixwindowsbugscolumn''.
  2. Inserte una fila exactamente para arreglar la tabla de errores de Windows. (¡más filas duplicarán filas en cualquier consulta de actualización ... mientras que cero filas no actualizarán ninguna fila en la consulta!)

  3. Busque y reemplace todos los ''DoCmd.RunSQL'' en su proyecto por la nueva función que se llamará ''runsqlerr''.

  4. Agregar nueva función a un módulo.

Public Sub runsqlerr(strx As String, Optional ustrans As Boolean) On Error GoTo err Dim TBLname As String, updloc As Long, endoftblloc As Long DoCmd.RunSQL strx, ustrans Exit Sub err: updloc = InStr(strx, "update ") If updloc <> 0 And err.Number = 3340 Then ''Query '''' is corrupt endoftblloc = InStr(updloc + 7, strx, " ") TBLname = Mid(strx, updloc + 7, endoftblloc - (updloc + 7)) strx = Replace(strx, TBLname, TBLname & ", fixwindowsbugs ", , 1) DoCmd.RunSQL strx, ustrans Else ''msgbox (err.Number & " " & err.Description err.Raise err.Number, "runsqlerr", err.Description End If End Sub

Eso es...


Nosotros y nuestros clientes hemos tenido problemas con esto en los últimos dos días y finalmente escribimos un documento para discutir el problema en detalle junto con algunas soluciones: http://fmsinc.com/MicrosoftAccess/Errors/query_is_corrupt/

Incluye nuestros hallazgos de que impacta las soluciones de Access cuando ejecuta consultas de actualización en tablas locales, tablas de acceso vinculadas e incluso tablas vinculadas de SQL Server.

También afecta a las soluciones que no son de Microsoft Access que utilizan el Motor de base de datos de acceso (ACE) para conectarse a las bases de datos de Access mediante ADO. Eso incluye aplicaciones de Visual Studio (WinForm), aplicaciones VB6 e incluso sitios web que actualizan bases de datos de Access en máquinas que nunca tenían Access u Office instaladas en ellas.

Este bloqueo incluso puede afectar las aplicaciones de Microsoft que usan ACE como PowerBI, Power Query, SSMA, etc. (no confirmado) y, por supuesto, otros programas como Excel, PowerPoint o Word que usan VBA para modificar bases de datos de Access.

Además de la obvia desinstalación de las Actualizaciones de seguridad ofensivas, también incluimos algunas opciones cuando no es posible desinstalar debido a permisos o distribución de aplicaciones de Access a clientes externos cuyas PC están fuera de su control. Eso incluye cambiar todas las consultas de Actualización y distribuir las aplicaciones de Access usando Access 2007 (minorista o en tiempo de ejecución) ya que esa versión no se ve afectada por las actualizaciones de seguridad.


Para aquellos que buscan automatizar este proceso a través de PowerShell , aquí hay algunos enlaces que encontré que pueden ser útiles:

Detectar y eliminar las actualizaciones ofensivas

Hay una secuencia de comandos de PowerShell disponible aquí https://www.arcath.net/2017/09/office-update-remover que busca en el registro una actualización específica de Office (pasada como un número kb) y la elimina mediante una llamada a msiexec.exe . Este script analiza los dos GUID de las claves del registro para generar el comando para eliminar la actualización adecuada.

Un cambio que sugeriría sería usar /REBOOT=REALLYSUPPRESS como se describe en Cómo desinstalar KB4011626 y otras actualizaciones de Office (Referencia adicional: https://docs.microsoft.com/en-us/windows/win32/msi/uninstalling-patches ). La línea de comando que está creando se ve así:

msiexec /i {90160000-0011-0000-0000-0000000FF1CE} MSIPATCHREMOVE={9894BF35-19C1-4C89-A683-D40E94D08C77} /qn REBOOT=REALLYSUPPRESS

El comando para ejecutar el script se vería así:

OfficeUpdateRemover.ps1 -kb 4484127

Evitar que se instalen las actualizaciones

El enfoque recomendado aquí parece estar ocultando la actualización . Obviamente, esto se puede hacer manualmente, pero hay algunos scripts de PowerShell que pueden ayudar con la automatización. Este enlace: https://www.maketecheasier.com/hide-updates-in-windows-10/ describe el proceso en detalle, pero lo resumiré aquí.

  1. Instale el Módulo de Windows Update PowerShell .
  2. Use el siguiente comando para ocultar una actualización por número KB:

    Hide-WUUpdate -KBArticleID KB4484127

Esperemos que esto sea de ayuda para alguien más.


Para resolver temporalmente este problema depende de la versión de Access en uso:
Acceso 2010 Desinstalar actualización KB4484127
Acceso 2013 Desinstalar actualización KB4484119
Acceso 2016 Desinstalar actualización KB4484113
Acceda a 2019 SI SE REQUIERE (por confirmar). Reducción de la versión 1808 (compilación 10352.20042) a la versión 1808 (compilación 10351.20054)
Office 365 ProPlus Downgrade de la versión 1910 (compilación 12130.20344) a una compilación anterior, consulte https://support.microsoft.com/en-gb/help/2770432/how-to-revert-to-an-earlier-version-of-office-2013-or-office-2016-clic


Use el siguiente módulo para implementar automáticamente la solución sugerida de Microsofts (usando una consulta en lugar de una tabla). Como precaución, primero haga una copia de seguridad de su base de datos.

Use AddWorkaroundForCorruptedQueryIssue() para agregar la solución y RemoveWorkaroundForCorruptedQueryIssue() para eliminarla en cualquier momento.

Option Compare Database Option Explicit Private Const WorkaroundTableSuffix As String = "_Table" Public Sub AddWorkaroundForCorruptedQueryIssue() On Error Resume Next With CurrentDb Dim tableDef As tableDef For Each tableDef In .tableDefs Dim isSystemTable As Boolean isSystemTable = tableDef.Attributes And dbSystemObject If Not EndsWith(tableDef.Name, WorkaroundTableSuffix) And Not isSystemTable Then Dim originalTableName As String originalTableName = tableDef.Name tableDef.Name = tableDef.Name & WorkaroundTableSuffix Call .CreateQueryDef(originalTableName, "select * from [" & tableDef.Name & "]") Debug.Print "OldTableName/NewQueryName" & vbTab & "[" & originalTableName & "]" & vbTab & _ "NewTableName" & vbTab & "[" & tableDef.Name & "]" End If Next End With End Sub Public Sub RemoveWorkaroundForCorruptedQueryIssue() On Error Resume Next With CurrentDb Dim tableDef As tableDef For Each tableDef In .tableDefs Dim isSystemTable As Boolean isSystemTable = tableDef.Attributes And dbSystemObject If EndsWith(tableDef.Name, WorkaroundTableSuffix) And Not isSystemTable Then Dim originalTableName As String originalTableName = Left(tableDef.Name, Len(tableDef.Name) - Len(WorkaroundTableSuffix)) Dim workaroundTableName As String workaroundTableName = tableDef.Name Call .QueryDefs.Delete(originalTableName) tableDef.Name = originalTableName Debug.Print "OldTableName" & vbTab & "[" & workaroundTableName & "]" & vbTab & _ "NewTableName" & vbTab & "[" & tableDef.Name & "]" & vbTab & "(Query deleted)" End If Next End With End Sub ''From https://excelrevisited.blogspot.com/2012/06/endswith.html Private Function EndsWith(str As String, ending As String) As Boolean Dim endingLen As Integer endingLen = Len(ending) EndsWith = (Right(Trim(UCase(str)), endingLen) = UCase(ending)) End Function

Puede encontrar el último código en mi repositorio de GitHub .

AddWorkaroundForCorruptedQueryIssue() agregará el sufijo _Table a todas las tablas que no sean del sistema, por ejemplo, la tabla IceCreams se renombraría a IceCreams_Table .

También creará una nueva consulta con el nombre de la tabla original, que seleccionará todas las columnas de la tabla renombrada. En nuestro ejemplo, la consulta se llamaría IceCreams y ejecutaría el SQL select * from [IceCreams_Table] .

RemoveWorkaroundForCorruptedQueryIssue() realiza las acciones inversas.

Probé esto con todo tipo de tablas, incluidas las tablas externas que no son MDB (como SQL Server). Pero tenga en cuenta que el uso de una consulta en lugar de una tabla puede conducir a consultas no optimizadas que se ejecutan en una base de datos de fondo en casos específicos, especialmente si sus consultas originales que utilizaron las tablas son de baja calidad o muy complejas.

(Y, por supuesto, dependiendo de su estilo de codificación, también es posible romper cosas en su aplicación. Por lo tanto, después de verificar que la solución generalmente funciona para usted, nunca es una mala idea exportar todos sus objetos como texto y usar algunos sustitutos de búsqueda magia para garantizar que cualquier aparición de nombres de tablas se ejecute en las consultas y no en las tablas).

En mi caso, esta solución funciona en gran medida sin ningún efecto secundario, solo necesitaba cambiar manualmente el nombre de USysRibbons_Table a USysRibbons , ya que no lo había marcado como una tabla del sistema cuando lo creé en el pasado.


VBA-Script para MS-Solución:

Se recomienda eliminar la actualización con errores, si es posible (si no prueba mi código), al menos para las versiones de MSI. Consulte la respuesta https://.com/a/58833831/9439330 .

Para las versiones CTR (Hacer clic y ejecutar), debe eliminar todas las actualizaciones de noviembre de Office, lo que puede causar serios problemas de seguridad (no estoy seguro de si se eliminarán las correcciones críticas).

De los comentarios de @ Eric:

  • Si usa Table.Tablename para vincular formularios, se desvinculan ya que el antiguo nombre de tabla ahora es un nombre de consulta.
  • OpenRecordSet(FormerTableNowAQuery, dbOpenTable) fallará (ya que ahora es una consulta, ya no es una tabla)

¡Precaución! Simplemente probado rápidamente en Northwind.accdb en Office 2013 x86 CTR ¡ Sin garantía!

Private Sub RenameTablesAndCreateQueryDefs() With CurrentDb Dim tdf As DAO.TableDef For Each tdf In .TableDefs Dim oldName As String oldName = tdf.Name If Not (tdf.Attributes And dbSystemObject) Then ''credit to @lauxjpn for better check for system-tables Dim AllFields As String AllFields = vbNullString Dim fld As DAO.Field For Each fld In tdf.Fields AllFields = AllFields & "[" & fld.Name & "], " Next fld AllFields = Left(AllFields, Len(AllFields) - 2) Dim newName As String newName = oldName On Error Resume Next Do Err.Clear newName = newName & "_" tdf.Name = newName Loop While Err.Number = 3012 On Error GoTo 0 Dim qdf As DAO.QueryDef Set qdf = .CreateQueryDef(oldName) qdf.SQL = "SELECT " & AllFields & " FROM [" & newName & "]" End If Next .TableDefs.Refresh End With End Sub

Para las pruebas:

Private Sub TestError() With CurrentDb .Execute "Update customers Set City = ''a'' Where 1=1", dbFailOnError ''works .Execute "Update customers_ Set City = ''b'' Where 1=1", dbFailOnError ''fails End With End Sub


currentDb.Execute el currentDb.Execute y Docmd.RunSQL con una función auxiliar. Eso puede preprocesar y cambiar la instrucción SQL si cualquier instrucción de actualización contiene solo una tabla. Ya tengo una tabla dual (una sola fila, una sola columna), así que elegí una opción de tabla falsa.

Nota : Esto no cambiará sus objetos de consulta. Solo ayudará a las ejecuciones de SQL a través de VBA. If you would like to change your query objects, use FnQueryReplaceSingleTableUpdateStatements and update your sql in each of your querydefs. Shouldn''t be a problem either.

Esto es solo un concepto (If it''s a single table update modify the sql before execution) . Adaptarlo según sus necesidades. Este método no crea consultas de reemplazo para cada tabla (que puede ser la forma más fácil pero tiene sus propios inconvenientes, es decir, problemas de rendimiento)

+ Puntos: puede seguir usando este ayudante incluso después de que MS solucione el error, no cambiará nada. En caso de que el futuro traiga otro problema, está listo para pre-process su SQL en un solo lugar.

Public Function Execute(Query As String, Optional Options As Variant) ''Direct replacement for currentDb.Execute If IsBlank(Query) Then Exit Function ''invalid db options remove If Not IsMissing(Options) Then If (Options = True) Then ''DoCmd RunSql query,True '' True should fail so transactions can be reverted ''We are only doing this so DoCmd.RunSQL query, true can be directly replaced by helper.Execute query, true. Options = dbFailOnError End If End If ''Preprocessing the sql command to remove single table updates Query = FnQueryReplaceSingleTableUpdateStatements(Query) ''Execute the command If ((Not IsMissing(Options)) And (CLng(Options) > 0)) Then currentDb.Execute Query, Options Else currentDb.Execute Query End If End Function Public Function FnQueryReplaceSingleTableUpdateStatements(Query As String) As String '' ON November 2019 Microsoft released a buggy security update that affected single table updates. ''https://.com/questions/58832269/getting-error-3340-query-is-corrupt-while-executing-queries-docmd-runsql Dim singleTableUpdate As String Dim tableName As String Const updateWord As String = "update" Const setWord As String = "set" If IsBlank(Query) Then Exit Function ''Find the update statement between UPDATE ... SET singleTableUpdate = FnQueryContainsSingleTableUpdate(Query) ''do we have any match? if any match found, that needs to be preprocessed If Not (IsBlank(singleTableUpdate)) Then ''Remove UPDATe keyword If (VBA.Left(singleTableUpdate, Len(updateWord)) = updateWord) Then tableName = VBA.Right(singleTableUpdate, Len(singleTableUpdate) - Len(updateWord)) End If ''Remove SET keyword If (VBA.Right(tableName, Len(setWord)) = setWord) Then tableName = VBA.Left(tableName, Len(tableName) - Len(setWord)) End If ''Decide which method you want to go for. SingleRow table or Select? ''I''m going with a fake/dual table. ''If you are going with update (select * from T) as T, make sure table aliases are correctly assigned. tableName = gDll.sFormat("UPDATE {0},{1} SET ", tableName, ModTableNames.FakeTableName) ''replace the query with the new statement Query = vba.Replace(Query, singleTableUpdate, tableName, compare:=vbDatabaseCompare, Count:=1) End If FnQueryReplaceSingleTableUpdateStatements = Query End Function Public Function FnQueryContainsSingleTableUpdate(Query As String) As String ''Returns the update ... SET statment if it contains only one table. FnQueryContainsSingleTableUpdate = "" If IsBlank(Query) Then Exit Function Dim pattern As String Dim firstMatch As String ''Get the pattern from your settings repository or hardcode it. pattern = "(update)+(/w|/s(?!join))*set" FnQueryContainsSingleTableUpdate = FN_REGEX_GET_FIRST_MATCH(Query, pattern, isGlobal:=True, isMultiline:=True, doIgnoreCase:=True) End Function Public Function FN_REGEX_GET_FIRST_MATCH(iText As String, iPattern As String, Optional isGlobal As Boolean = True, Optional isMultiline As Boolean = True, Optional doIgnoreCase As Boolean = True) As String ''Returns first match or "" If IsBlank(iText) Then Exit Function If IsBlank(iPattern) Then Exit Function Dim objRegex As Object Dim allMatches As Variant Dim I As Long FN_REGEX_GET_FIRST_MATCH = "" On Error GoTo FN_REGEX_GET_FIRST_MATCH_Error Set objRegex = CreateObject("vbscript.regexp") With objRegex .Multiline = isMultiline .Global = isGlobal .IgnoreCase = doIgnoreCase .pattern = iPattern If .test(iText) Then Set allMatches = .Execute(iText) If allMatches.Count > 0 Then FN_REGEX_GET_FIRST_MATCH = allMatches.item(0) End If End If End With Set objRegex = Nothing On Error GoTo 0 Exit Function FN_REGEX_GET_FIRST_MATCH_Error: FN_REGEX_GET_FIRST_MATCH = "" End Function

Ahora solo CTRL+F

Busque y reemplace docmd.RunSQL con helper.Execute

Busque y reemplace [currentdb|dbengine|or your dbobject].execute con helper.execute

¡que te diviertas!