使用每日更新的访问表自动刷新SQL Server后端

时间:2019-04-23 05:54:44

标签: sql-server ms-access access-vba odbc dsn

摘要::我有一个本地Access数据库,其中包含订单,并且每天早晨由Windows任务启动的自动VBA例程进行更新。详细来说,每天都会使用本地.csv文件添加新订单,并使用新信息更新现有订单,该文件会在上午5:30放置在共享文件夹环境中。

现在,我有一个需要更新的SQL Server和本地表的精确副本,在最佳情况下,是在进行本地更新之后。这是必要的,因为我将SQL Server用作自动订单分发工具的后端,以后将有约50名员工使用该工具。

我尝试过的操作:我正在本地表上完全运行本地更新例程,该表始终是本地表,以确保更新过程顺利进行。为了更新SQL表,我尝试通过创建链接表来实现它,但是,数据集并未转移到SQL Server。这很奇怪,因为当我在链接表中手动更改单个字段时,所做的更改会立即反映在SQL Server表中。只是基于VBA的进程不会在SQL Server中更新。

代码:

Sub Sync_SQL()

Dim myDB As DAO.Database
Set myDB = CurrentDb

Dim strSQL As String

Dim qdf As QueryDef

' Erstellt einen temporären Query mit einem ODBC-Connection String zur Verbindung mit dem SQL Server
Set qdf = CurrentDb.CreateQueryDef("SyncDB")
qdf.Connect = "ODBC;Driver={SQL Server};server=XX.X.XXX.XX;database=OPM;uid=USID;pwd=PWD;"

' Löscht alle noch offenen Aufträge aus dem SQL-Server
qdf.SQL = "DELETE FROM [OPM].[dbo].[ReiseMaster] WHERE NOT [Name of Employee] = '---------';"
qdf.ReturnsRecords = False

' Führt den Query aus und misachtet dabei jegliche Dialogfelder
DoCmd.SetWarnings False
DoCmd.OpenQuery "SyncDB"
DoCmd.SetWarnings True

' Fügt aktuell offene Aufträge in den SQL-Server ein
myDB.Execute "INSERT INTO [dbo_ReiseMaster] SELECT * FROM [ReiseMaster] WHERE NOT [Name of Employee] = '---------';"

' Leert den Statistik-Table (sollte in Zukunft anders funktionieren)
qdf.SQL = "DELETE FROM [OPM].[dbo].[Statistics];"
qdf.ReturnsRecords = False

' Führt den Query aus und misachtet dabei jegliche Dialogfelder
DoCmd.SetWarnings False
DoCmd.OpenQuery "SyncDB"
DoCmd.SetWarnings True

' Lädt den Statistik-Table mit den neuen Werten hoch (sollte in Zukunft nur noch für neue Aufträge erfolgen, um Performance auch nach längerer Laufzeit der Datenbank gering zu halten)
myDB.Execute "INSERT INTO [dbo_Statistics] SELECT * FROM [Statistics];"

' Setzt die aktive Verbindung zurück und löscht den temporären Query
Set qdf = Nothing
myDB.QueryDefs.Delete "SyncDB"
myDB.QueryDefs.Refresh

End Sub

结果:特别是,对链接表的以下更改将不会反映在SQL Server中:

myDB.Execute "INSERT INTO [dbo_ReiseMaster] SELECT * FROM [ReiseMaster] WHERE NOT [Name of Employee] = '---------';"

虽然Access文件中的链接表dbo_ReiseMaster包含更新的值,但它们没有被上载到SQL Server。

如何确保本地Access表(无论以何种方式处理数据)始终将更改转移到SQL Server?

1 个答案:

答案 0 :(得分:1)

您不能使用单个连接对象,然后访问的“希望”知道要使用哪个表。您在单个连接对象上执行sql,因此insert和source表将驻留在该一个远程连接上。你不能那样做。

如果源表存在sql服务器端会发生什么?

但是,转储所有查询连接内容。只需将表链接到服务器即可。

您现在可以通过访问权限编写和使用标准sql,并像使用本地表一样使用这两个表。

因此,您可以去:    将strSQL暗淡为字符串

strSQL = "INSERT INTO [ReiseMasterLinked] " & _
        "SELECT * FROM [ReiseMaster] WHERE NOT [Name of Employee] = '---------';"

currentdb.Execute strSQL

因此,即使一个表链接到sql server,也可以对两个表使用sql,但是必须使用链接表。您无需处理或查看或使用连接对象,因为它总是会应用于一个连接对象。但是,Access的特殊之处在于,您可以编写包含链接表和本地表的sql-并且它将解析两个表所基于的连接(或者实际上,一个未链接的表是本地的,而另一个表是本地的。链接表。

编辑

这是另一个例子。但是请注意我如何注释掉.Execute命令,并将其替换为docmd.RunSQL。

Sub AppendTest()

  Dim strSQL     As String

  strSQL = "INSERT INTO tblHotelsSQL " & _
           "SELECT * FROM tblHotelsLOCAL WHERE NOT tblHotelsLOCAL.HotelName = '-----'"

  'CurrentDb.Execute strSQL, dbFailOnError
  DoCmd.RunSQL strSQL

End Sub

运行速度较慢,并且将命令包装在事务中-因此您可以对提示回答“是”或“否”,但是它给出了关于查询为什么不能或没有运行的更详细的错误消息。同样,请注意如何不需要连接字符串。为了使以上功能正常运行,您可以快速双击链接表到SQL Server,以确保链接表正常运行(如果显示数据-也许尝试编辑一行-移开),这样可以确保链接表是可读写的。