Как сделать сквозной / проходной запрос редактируемым?

В Microsoft Access 2007 с серверной частью SQL Server мы обычно берем связанную таблицу из SQL Server как Form.RecordSource редактируемой формы для изменения данных одной таблицы. Для редакций кросс-таблиц используется локальный запрос, который объединяет поля из нескольких связанных таблиц. Локальный запрос должен сам обновляться, чтобы изменять данные в форме редактирования.

Теперь мы планируем заменить все локальные запросы на сквозные запросы, чтобы напрямую использовать собственные таблицы SQL Server.

Я попытался создать очень простой промежуточный запрос с именем qrySelProductsPassThroughEditable со следующей строкой SQL:

SELECT dbo.Products.ID, dbo.Products.Name FROM dbo.Products;

Поле ID - это поле IDENTITY, определенное как первичный ключ в SQL Server в качестве определения:

CREATE TABLE [dbo].[Products](
    [ID] [int] IDENTITY(1,1) NOT NULL,
        ....
)

Но таблица данных, возвращаемая сквозным запросом Access, вообще не редактируется. Так что его нельзя использовать как .RecordSource и для формы редактирования.

Это противоречит ссылке, в которой говорится, что Passthru запрос содержит все первичные ключи всех задействованных таблиц, запрос будет редактируемым.

Заключение добавлено апостериори

В приведенных ниже обсуждениях сквозной запрос в файлах .accdb, .accde или .accdr (среда выполнения Access) Microsoft Access 2007 всегда доступен только для чтения и никогда не редактируется. Вы должны использовать его как окончательный список или как источник записи отчета, а не для формы, для которой вы должны использовать связанную таблицу, или обычный запрос с возможностью записи, включающий связанные таблицы для ввода-вывода данных.


person jacouh    schedule 19.09.2013    source источник
comment
Я не знаю, что сквозные запросы можно обновлять. У меня сложилось впечатление, что производят наборы записей только для чтения.   -  person HK1    schedule 19.09.2013
comment
Если это так, то как можно напрямую редактировать таблицы в SQL Server с помощью формы доступа: нужно проходить по связанным таблицам?   -  person jacouh    schedule 19.09.2013


Ответы (4)


В соответствии с моим комментарием выше и ответом Явара я не знаю, что сквозные запросы когда-либо редактируются / обновляются. Они редактируются в том смысле, что вы можете редактировать сохраненный объект Pass Through Query, но я не верю, что Pass Through Query может создать редактируемый набор записей.

Существует два основных метода подключения Access к источнику данных, не относящемуся к Access.

Первый и самый популярный метод заключается в использовании некоторой формы связанных таблиц, обычно связанных таблиц ODBC. Существует множество методов использования связанных таблиц ODBC с MS Access, но большинство разработчиков предпочитают использовать подключения без DSN, которые обновляются или восстанавливаются (удаляются и повторно подключаются) во время запуска вашего приложения. Имейте в виду, что когда вы используете ODBC, вы также все еще используете DAO. DAO - это объект доступа к данным по умолчанию, встроенный в MS Access, и даже если вы специально не пишете какой-либо код DAO, MS Access все еще использует DAO под капотом, чтобы связать ваши формы, отчеты и запросы с вашим источником данных. В случае ODBC у вас фактически есть два действующих уровня доступа к данным: DAO и ODBC. Но вы можете использовать ODBC / DAO с довольно приличной производительностью и без написания кода (кроме поддержки связанных таблиц ODBC).

Второй способ - использовать ADO. Вопреки распространенному мнению, это не означает, что вы должны использовать несвязанные формы. Но это означает, что вам нужно написать больше кода, чем при использовании JET / DAO / MSAccess или DAO / ODBC / SSQL Server. Вы должны написать код для переноса записей из вашей базы данных в ADO Recordset, а затем использовать код для привязки вашей формы к этому Recordset. Вам нужно написать больше кода, чтобы дочерние формы синхронизировались с родительскими формами, чтобы вставлять внешние ключи в дочерние формы при создании новых записей, а также для множества других вещей, таких как фильтрация и сортировка, в качестве встроенной фильтрации и сортировки формы. параметры обычно не работают с наборами записей ADO. ADO - отличный способ поговорить с SQL Server, поскольку он действительно дает вам большой контроль, но из-за интенсивного кода и из-за того, что связанные таблицы ODBC работают так хорошо, большинство разработчиков не рекомендуют использовать ADO, если нет другого способа сделать то, что ты хочешь сделать. Одним из примеров этого является вызов хранимых процедур. Я считаю, что сквозные запросы можно использовать для вызова хранимых процедур, но я также думаю, что здесь есть некоторые ограничения (например, использование параметров). Я считаю, что в большинстве случаев разработчики используют ADO для вызова хранимых процедур. Я часто использую ADO, но я мало использую хранимые процедуры (пока), поэтому у меня мало информации по этому поводу.

Еще одна вещь, о которой стоит упомянуть, заключается в том, что DAO с ODBC использует «ленивую загрузку», но ADO заставляет вас извлекать все данные, что может занять очень много времени и потреблять много памяти, если у вас> миллионов строк. В противном случае вам нужно будет реализовать какой-то пейджинг.

Моя собственная функция для создания единой таблицы, связанной с ODBC без DSN, приведена ниже. Если вы новичок в Access и новичок в VBA, это, вероятно, не будет иметь для вас большого смысла. Код удаляет любое определение таблицы, которое уже существует для таблицы, которую вы пытаетесь связать, что немного опасно, потому что я считаю, что он может удалить локальную несвязанную таблицу, которая вам не нужна. Обработка ошибок здесь тоже не очень высока, но в большинстве онлайн-примеров кода нет хорошей обработки ошибок из-за связанных с этим сложностей. Создание индексов первичного ключа для связанной таблицы не всегда необходимо. Я просто встроил его в свою функцию, потому что он мне понадобился один раз для конкретного проекта, поэтому теперь я оставляю его там и использую, к лучшему или к худшему.

Чтобы правильно использовать этот код, вам действительно нужно где-то иметь список всех ваших связанных таблиц и выполнять итерацию по этому списку и вызывать эту функцию для каждой таблицы. Эта функция позволяет связать таблицу, используя имя, отличное от фактического имени в SQL Server. У вас также должен быть способ создания допустимой строки подключения ODBC, которая также должна быть передана в эту функцию.

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

Есть несколько действительно хороших ресурсов, которые вы должны изучить, касающиеся DAO, ADO, Pass Through Queries, SQL Server и т. Д.:

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

Вот пример привязки формы к набору записей ADO. Это немного вводит в заблуждение, потому что лучше всего иметь глобальный объект подключения, который остается открытым во время выполнения приложения. Это позволяет использовать автоматически обновляемые наборы записей ADO. Использование этой практики также может сделать ваш набор записей объектом уровня формы.

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

person HK1    schedule 19.09.2013

Существует более простой, плохо документированный способ открыть любой оператор SQL Server Select (таблица, представление или sql-select со многими соединенными таблицами) в окне запроса MsAccess и быть доступным для редактирования / обновления:

Откройте окно запроса Access и введите свой оператор SQL. Замените имя (я) таблицы полной строкой ODBC для SQL Server в квадратных скобках, после точки, а также схемы и имени таблицы, как в следующем примере:

До:

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

После:

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

Теперь запрос обновляется:  В окне запроса доступа отображаются данные из SQL Server в соответствии с оператором SQL Select

Примечания:

  • Не каждый оператор SQL делает таблицу или представление обновляемыми. Информацию об ограничениях и ограничениях см. В разделе «Обновляемые представления» в CREATE VIEW (Transact-SQL) (https://msdn.microsoft.com/en-us/library/ms187956.aspx).
  • Базовая таблица, которую вы хотите обновлять в Access, должна иметь метку времени или столбец RowVersion.
person Alpan    schedule 03.09.2015

Наборы результатов сквозных запросов не редактируются, но запросы Access, основанные на связанных таблицах, определенно доступны.

person Yawar    schedule 19.09.2013

Да, это правда с «вторым методом - использовать ADO», что свойства LinkMasterFields и LinkChildFields не работают в мультиформ, а набор записей ADO не работает в отчете Access 2013, поэтому я использую сквозной запрос. Я использую ADP + ADPX.accde для имитации свойств LinkMasterFields и LinkChildFields в мультиформных и мульти-отчетах.

person Irish Joy    schedule 14.09.2014