How to make a passthrough / passthru query editable?

怎甘沉沦 提交于 2019-11-28 13:37:07

In line with my comment above and the answer by Yawar, I'm not aware that Pass Through Queries are ever editable/updateable. They are editable in the sense that you can edit a save Pass Through Query object, but I don't believe it's possible for a Pass Through Query to produce an editable recordset.

There are basically two methods to connect Access to a non-Access data source.

The first method, and most popular, is to use some form of linked tables, generally ODBC linked tables. There are a variety of methods of using ODBC linked tables with MS Access but by what most developers prefer is to use DSN-Less connections that get refreshed or rebuilt (deleted and reconnected) at the time that your application starts. Be aware that when you use ODBC, you are also still using DAO. DAO is the default data access object built into MS Access and even when you don't specifically write any DAO code, MS Access is still using DAO under the hood to link your forms, reports and queries to your data source. In the case of ODBC, you actually end up having two data access layers at work, DAO and ODBC. But you can use ODBC/DAO with pretty decent performance and without writing code (other than to maintain the ODBC linked tables).

The second method is to use ADO. Contrary to popular belief, this does not mean that you have to use unbound forms. But it does mean that you have to write more code than using JET/DAO/MSAccess or DAO/ODBC/SSQL Server. You have to write code to bring in records from your database into and ADO Recordset and then use code to bind your form to that Recordset. You have to write more code to keep child forms in sync with parent forms, to insert foreign keys into child forms when new records are created, and for a variety of other things too like filtering and sorting as the form's built-in filtering and sorting options usually do not work with ADO recordsets. ADO is a great way to talk to SQL Server as it really gives you a lot of control, but because it's code intense, and because ODBC Linked Tables work so well, most developers do not recommend using ADO unless there's no other way to do what you want to do. One example of this is calling Stored Procedures. I believe Pass Through Queries can be used to call Stored Procedures but I also think there are some limitations there (such as using Parameters). I believe in most cases developers use ADO to call stored procedures. I use ADO a lot but I don't use Stored Procedures much (not yet) so I don't have a lot of information on that.

One other thing worth mentioning is that DAO with ODBC uses "lazy loading" but ADO forces you to pull all of the data which can be very time consuming and consume a lot of memory if you have > millions of rows. Or else you will need to implement some kind of paging.

My own function to create a single DSN-Less ODBC Linked table is below. If you're new to Access and new to VBA this probably won't make a lot of sense to you. The code deletes any table definition that already exists for the table you're trying to link, which is a little dangerous because I believe it could delete a local, non-linked table which you wouldn't want. The error handling in here isn't really up to speed either, but most online example code doesn't have good error handling in it because of the complications that involves. The creation of Primary Key Indexes on a linked table isn't always necessary. I just have it built into my function because I needed it one time for a specific project so now I leave it in there and use it, for better or for worse.

To make proper use of this code you really need to have a list of all your linked tables somewhere and iterate through that list and call this function for each table. This function allows you to link the table up using a different name than it's actual name in SQL Server. You also need to have a way of building a valid ODBC connection string which must be passed into this function too.

Private Sub LinkODBCTable(sSourceTableName As String, _
                        sLocalTableName As String, _
                        sPrimaryKeyField As String, _
                        sConString As String)

    Dim dbCurrent As DAO.Database
    Dim tdfCurrent As DAO.TableDef
    Set dbCurrent = DBEngine.Workspaces(0).Databases(0)

    On Error Resume Next
    'Be Careful, this could delete a local, non-linked table.
    dbCurrent.TableDefs.Delete sLocalTableName
    If Err.Number <> 0 Then
        If Err.Number = 3011 Then
            'Table does not exist
        Else
            MsgBox "Error in LinkODBCTable" & vbCrLf & vbCrLf & Err.Number & " " & Err.Description
        End If
        Err.Clear
    End If

    On Error GoTo 0

    Set tdfCurrent = dbCurrent.CreateTableDef(sLocalTableName)
    tdfCurrent.Connect = sConString
    tdfCurrent.sourceTableName = sSourceTableName
    dbCurrent.TableDefs.Append tdfCurrent

    On Error Resume Next
    If sPrimaryKeyField <> "" Then
        dbCurrent.Execute "CREATE INDEX __UniqueIndex ON [" & sLocalTableName & "] (" & sPrimaryKeyField & ")", dbFailOnError
        If Err.Number <> 0 Then
            If Err.Number = 3283 Then
                'Primary Key Already Exists
            Else
                MsgBox "Error in LinkODBCTable" & vbCrLf & vbCrLf & Err.Number & " " & Err.Description
            End If
            Err.Clear
        End If
    End If

    Set tdfCurrent = Nothing
    Set dbCurrent = Nothing
End Sub

There are a few really good resources you should check out concerning DAO, ADO, Pass Through Queries, SQL Server, etc:

http://technet.microsoft.com/en-us/library/bb188204%28v=sql.90%29.aspx
http://www.utteraccess.com/wiki/Choosing_between_DAO_and_ADO

Here's an example of binding a form to an ADO Recordset. It's a little misleading though because it's best to have a global connection object that stays open during the runtime of the application. This allows you to use ADO recordsets that are automatically updateable. Using this practice might also make your recordset a form level object.

http://msdn.microsoft.com/en-us/library/office/bb243828%28v=office.12%29.aspx

There is an easier non well documented way to open any SQL Server Select Statement (a table, a view or a sql-select with many joined tables) in a MsAccess query window and be editable/updatable:

Open an Access query window and enter your SQL Statement. Replace the table name(s) with the full ODBC string to the SQL Server inside square brackets, following by a dot and the schema and table name like in the following example:

Before:

SELECT SOH.SalesOrderID, SOH.OrderDate
FROM   Sales.SalesOrderHeader as SOH 

After:

SELECT SOH.SalesOrderID, SOH.OrderDate
FROM   [ODBC;Driver=SQL Server;Server=myServer;Database=AdventureWorks2012;Trusted_Connection=Yes;MarsConn=yes;].Sales.SalesOrderHeader as SOH 

The Query is now updatable:

Remarks:

  • Not every SQL Statement makes a table or view updatable. For limitations and restrictions see the section 'Updatable Views' in CREATE VIEW (Transact-SQL) (https://msdn.microsoft.com/en-us/library/ms187956.aspx).
  • The underlying table you want to be updatable in Access must have a timestamp or RowVersion column.

Pass-through queries result sets are not editable, but Access queries based on linked tables definitely are.

Yes its true with "The second method is to use ADO" that LinkMasterFields and LinkChildFields properties are not working in a multi-form and ADO recordset is not working in Access 2013 report, so there I'm using Pass-through query. I'm using ADP+ ADPX.accde to simulate LinkMasterFields and LinkChildFields properties in multi-form and multi-report.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!