使用每日更新的访问 table 自动刷新 SQL 服务器后端
Automatically refresh SQL Server backend with daily updated Access table
总结: 我有一个包含订单的本地 Access 数据库,每天早上由 VBA 自动例程更新,由 Windows 任务。详细地说,每天都会添加新订单,并使用本地 .csv
文件更新现有订单的新信息,该文件在早上 5:30am 放在共享文件夹环境中。
现在,我有一个需要更新的 SQL 服务器和本地 table 的精确副本,最好是在本地更新完成后。这是必要的,因为我使用 SQL 服务器作为自动订单分发工具的后端,将来会有大约 50 名员工使用。
我已经尝试过: 我是 运行 完全在本地 table 上的本地更新例程,它现在是并且永远是本地的以确保更新过程顺利进行。为了更新 SQL table 我试图通过创建链接 table 来实现它,但是,数据集没有传输到 SQL 服务器。这很奇怪,因为当我在链接 table 中手动更改单个字段时,更改会立即反映在 SQL 服务器 table 中。只有基于 VBA 的进程未在 SQL 服务器中更新。
代码:
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
结果: 特别是,以下对链接 table 的更改不会反映在 SQL 服务器中:
myDB.Execute "INSERT INTO [dbo_ReiseMaster] SELECT * FROM [ReiseMaster] WHERE NOT [Name of Employee] = '---------';"
虽然 Access 文件中的链接 table dbo_ReiseMaster
包含更新的值,但它们没有上传到 SQL 服务器。
我如何确保本地访问 table(无论我以何种方式处理数据)总是将更改传输到 SQL 服务器?
您不能使用单个连接对象然后“希望”access 知道要使用什么 table。您在单个连接对象上执行 sql,因此插入和源 table 将驻留在那个远程连接上。你不能那样做。
如果源 table 存在 sql 服务器端会怎样?
但是,转储所有查询连接内容。只需 link table 到服务器。
您现在可以编写和使用来自 access 的标准 sql,并像在本地一样使用两个 table。
所以,你可以去:
将 strSQL 调暗为字符串
strSQL = "INSERT INTO [ReiseMasterLinked] " & _
"SELECT * FROM [ReiseMaster] WHERE NOT [Name of Employee] = '---------';"
currentdb.Execute strSQL
因此,您可以对两个 table 使用 sql,即使一个 linked 到 sql 服务器,但您必须使用 linked tables。您无需处理、查看或使用连接对象,因为它始终适用于一个连接对象。但是,Access 非常特殊,因为您可以编写包含 linked tables 和本地 tables 的 sql - 它将解析两个 tables 是基于(或者事实上,一个 table 不是 linked 是本地的,另一个是 linked table.
编辑
这是另一个例子。但请注意我是如何注释掉 .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
这 运行 速度较慢,并将命令包装在一个事务中 - 因此您可以对提示回答是或否,但它会提供更详细的错误消息,说明查询无法执行的原因,或者没有 运行。再次注意不需要连接字符串。要使上述工作正常,可以快速双击 linked table 到 SQL 服务器以确保 linked table 全部正常工作很好(如果它显示数据 - 也许尝试编辑一行 - 离开,这将确保 linked table 是 read/write.
总结: 我有一个包含订单的本地 Access 数据库,每天早上由 VBA 自动例程更新,由 Windows 任务。详细地说,每天都会添加新订单,并使用本地 .csv
文件更新现有订单的新信息,该文件在早上 5:30am 放在共享文件夹环境中。
现在,我有一个需要更新的 SQL 服务器和本地 table 的精确副本,最好是在本地更新完成后。这是必要的,因为我使用 SQL 服务器作为自动订单分发工具的后端,将来会有大约 50 名员工使用。
我已经尝试过: 我是 运行 完全在本地 table 上的本地更新例程,它现在是并且永远是本地的以确保更新过程顺利进行。为了更新 SQL table 我试图通过创建链接 table 来实现它,但是,数据集没有传输到 SQL 服务器。这很奇怪,因为当我在链接 table 中手动更改单个字段时,更改会立即反映在 SQL 服务器 table 中。只有基于 VBA 的进程未在 SQL 服务器中更新。
代码:
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
结果: 特别是,以下对链接 table 的更改不会反映在 SQL 服务器中:
myDB.Execute "INSERT INTO [dbo_ReiseMaster] SELECT * FROM [ReiseMaster] WHERE NOT [Name of Employee] = '---------';"
虽然 Access 文件中的链接 table dbo_ReiseMaster
包含更新的值,但它们没有上传到 SQL 服务器。
我如何确保本地访问 table(无论我以何种方式处理数据)总是将更改传输到 SQL 服务器?
您不能使用单个连接对象然后“希望”access 知道要使用什么 table。您在单个连接对象上执行 sql,因此插入和源 table 将驻留在那个远程连接上。你不能那样做。
如果源 table 存在 sql 服务器端会怎样?
但是,转储所有查询连接内容。只需 link table 到服务器。
您现在可以编写和使用来自 access 的标准 sql,并像在本地一样使用两个 table。
所以,你可以去: 将 strSQL 调暗为字符串
strSQL = "INSERT INTO [ReiseMasterLinked] " & _
"SELECT * FROM [ReiseMaster] WHERE NOT [Name of Employee] = '---------';"
currentdb.Execute strSQL
因此,您可以对两个 table 使用 sql,即使一个 linked 到 sql 服务器,但您必须使用 linked tables。您无需处理、查看或使用连接对象,因为它始终适用于一个连接对象。但是,Access 非常特殊,因为您可以编写包含 linked tables 和本地 tables 的 sql - 它将解析两个 tables 是基于(或者事实上,一个 table 不是 linked 是本地的,另一个是 linked table.
编辑
这是另一个例子。但请注意我是如何注释掉 .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
这 运行 速度较慢,并将命令包装在一个事务中 - 因此您可以对提示回答是或否,但它会提供更详细的错误消息,说明查询无法执行的原因,或者没有 运行。再次注意不需要连接字符串。要使上述工作正常,可以快速双击 linked table 到 SQL 服务器以确保 linked table 全部正常工作很好(如果它显示数据 - 也许尝试编辑一行 - 离开,这将确保 linked table 是 read/write.