Использовать функцию доступа в сквозном запросе SQL - PullRequest
0 голосов
/ 09 мая 2019

У меня есть интерфейс MS Access с базой данных Oracle SQL.

Я пытаюсь создать сквозной запрос, содержащий функцию в Access.Функция предназначена для установки jobnumber в зависимости от того, что пользователь вводит на экране входа в систему.

SELECT 
    CC_QAQC_SPEC_MASTER.JOBNUMBER, 
    CC_QAQC_SPEC_MASTER.SPECSECTION,
    CC_QAQC_SPEC_MASTER.SPECDESCRIPTION,
    CC_QAQC_SPEC_MASTER.ID
FROM 
    CC_QAQC_SPEC_MASTER
WHERE 
    CC_QAQC_SPEC_MASTER.JOBNUMBER=GET_QAQC_JOB()
ORDER BY 
    CC_QAQC_SPEC_MASTER.SPECSECTION, 
    CC_QAQC_SPEC_MASTER.SPECDESCRIPTION;

Когда я запускаю вышеупомянутое, я получаю сообщение об ошибке, которое говорит:

ODBC - сбой вызова [Oracle] [ODBC] [Ora] ORA-00942: таблицаили представление не существует (# 942)

Ответы [ 2 ]

2 голосов
/ 10 мая 2019

Что ж, поскольку sql отправляется в Oracle «сырым» способом, то, конечно, база данных на стороне сервера не знает, что делать с функцией VBA.

Итак, одним из возможных решений было бы воссоздание функции VBA как функции оракула масштабирования.

Однако, поскольку данная функция не имеет параметров, мы можем предположить, что функция возвращает заданное значение - чертовски близко к статическому или значение, которое вы хотите / хотите передать оракулу.

Подход означает, что мы должны разрешить функцию на стороне клиента ДО того, как мы попытаемся использовать или выполнить этот запрос PT.

Итак, я рекомендую вам взять вышеупомянутый запрос PT и скопировать его. (сторона доступа). Теперь у вас есть два запроса PT.

Теперь в коде мы берем sql, модифицируем его, помещаем его во 2-й запрос, и теперь вы можете запускать и использовать этот проходной запрос (для отчета, наборов записей, форм или чего-либо еще)

Итак, ваш код будет выглядеть так:

Sub MyOraclePT()

  Dim strSQL     As String

  strSQL = CurrentDb.QueryDefs("PT1").SQL    ' <-- this change

  strSQL = Replace(strSQL, "GET_QAQC_JOB()", GET_QAQC_JOB())

  CurrentDb.QueryDefs("PT2").SQL = strSQL

  ' now you can open or use this query.

  '
  Dim rst     As DAO.Recordset
  Set rst = CurrentDb.OpenRecordset("PT2")

  ' or open a report/form based on that PT2 query
  ' such as
  DoCmd.OpenReport "MyReport", acViewPreview


End Sub

Итак, мы использовали два запроса PT, потому что первый - это sql, который у вас есть, как указано выше. Затем мы модифицируем второй запрос PT, чтобы заменить значение функции фактическим значением функции.

Выше предполагается, что функция является числом (а не строкой). Если столбец CC_QAQC_SPEC_MASTER.JOBNUMBER был строкой, то вы могли бы / могли бы заключить одинарные кавычки вокруг имени функции в первом запросе PT.

Я также отмечаю ошибку / синтаксическую ошибку, как у вас есть:

WHERE 
    CC_QAQC_SPEC_MASTER.JOBNUMBER)=GET_QAQC_JOB()

Вверху я вижу беспризорное ")" сверху - вы хотите это исправить.

1 голос
/ 09 мая 2019

Предполагая, что эта функция написана на VBA в Access, вы не можете вызвать ее из запроса. Я полагаю, что DML в запросе полностью передается исходной системе, в данном случае Oracle. Oracle не знает, что это за функция и что делает.

Option-1 : отправить запрос через ADO.NET в VBA

Отказаться от сквозных объектов запроса в Access. Выполните запрос от VBA, соединяющейся с Oracle через ADO или что-то подобное. Существует множество ресурсов о том, как использовать ADO для извлечения данных из внешних источников данных, таких как Как открыть объекты ADO Connection и Recordset . Здесь - пример использования DAO.

Вариант-2 : завернуть сквозной запрос в другой запрос

Доступ позволяет создавать запросы, которые вызывают другие запросы. Создайте сквозной запрос без предиката WHERE. Это сквозной запрос. Создайте другой запрос доступа, который вызывает сквозной запрос. Это запрос переноса. Запрашивающий запрос (поскольку он является собственным SQL-кодом Access) должен иметь параметр, который вы используете для фильтрации результирующего набора.

Полное раскрытие. Я не пробовал это с Oracle.

Теперь, если сквозной запрос захватывает много данных. Эта опция не будет работать хорошо.

Option-3 : динамическое создание проходного запроса

У вас есть событие (нажатие кнопки или что-то еще), вызывающее подпроцедуру VBA, которая динамически создает и назначает SQL для запроса:

Public Sub foo()
    Let qaqc_job_number = GET_QAQC_JOB()
    Set Query = CurrentDb.QueryDefs("<your-pass-thru-function-name>")

    Let sql_job_data = "SELECT" & _
                       "CC_QAQC_SPEC_MASTER.JOBNUMBER, " & _
                       "CC_QAQC_SPEC_MASTER.SPECSECTION, " & _
                       "CC_QAQC_SPEC_MASTER.SPECDESCRIPTION, " & _
                       "CC_QAQC_SPEC_MASTER.ID " & _
                       "FROM " & _
                       "CC_QAQC_SPEC_MASTER " & _
                       "WHERE " & _
                       "CC_QAQC_SPEC_MASTER.JOBNUMBER)= " & qaqc_job_number & " " & _
                       "Order BY " & _
                       "CC_QAQC_SPEC_MASTER.SPECSECTION, " & _
                       "CC_QAQC_SPEC_MASTER.SPECDESCRIPTION; "

    Let Query.Sql = sql_job_data

End Sub

Затем вы запускаете запрос.

Все в SQL, который вы вставляете в этот объект запроса Access, должно существовать в Oracle и ТОЛЬКО в Oracle.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...