Реактивный двигатель (Access): передача списка значений в хранимую процедуру - PullRequest
0 голосов
/ 03 апреля 2011

В настоящее время я пишу надстройку Excel на основе VBA, которая в значительной степени основана на базе данных Jet (я использую пакет Office 2003 - проблема будет такой же, как и в более поздней версии Office).

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

Позвольте мне привести простой пример для описания моей проблемы: предположим, что мое приложение позволяет конечным пользователям выбирать идентификаторы заказов, для которых они хотели бы получить подробную информацию.Вот определение таблицы:

Таблица tblOrders: OrderID LONG, OrderDate DATE, (другие поля)

Конечный пользователь может выбрать один или несколько OrderID, отображаемых вform - ему / ей нужно просто поставить галочку напротив соответствующих идентификаторов OrderID, для которых он / она хочет получить подробную информацию (OrderDate и т. д.).

Поскольку я заранее не знаю, сколько OrderID он / она выберет, я мог бы динамически создавать SQL-запрос в коде VBA, каскадируя предложения WHERE на основе выбора, сделанного в форме:

SELECT * FROM tblOrders WHERE OrderID = 1 OR OrderID = 2 OR OrderID = 3

или, что намного проще, с помощью ключевого слова IN:

SELECT * FROM tblOrders WHERE OrderID IN (1,2,3)

Теперь, если я превращу этот простой запрос в хранимую процедуру, чтобы я мог динамически передавать список идентификаторов OrderID, которыми я хочу бытьотображается, как я должен сделать?Я уже пробовал такие вещи, как:

CREATE PROCEDURE spTest (@OrderList varchar) AS
  SELECT * FROM tblOrders WHERE OrderID IN (@OrderList)

Но это не работает (я ожидал этого), потому что @OrderList интерпретируется как строка (например, "1,2,3"), а не каксписок длинных значений.(Я адаптировался из кода, найденного здесь: Передача списка / массива в хранимую процедуру SQL Server )

Я бы хотел избежать решения этой проблемы с помощью чистого кода VBA (то есть динамического назначения списказначений для запроса, который жестко задан в моем приложении), насколько это возможно.Я бы понял, если это когда-либо будет невозможно.

Любая подсказка?

1 Ответ

1 голос
/ 03 апреля 2011

Вы можете динамически создавать строку оператора запроса.В SQL Server вы можете иметь функцию, возвращаемое значение которой - TABLE, и вызывать эту функцию как встроенную, как если бы она была таблицей.Или в JET вы также можете создать kludge - временную таблицу (или постоянную таблицу, которая выполняет функцию временной таблицы), которая содержит значения в вашем списке, по одному на строку, и объединение в этой таблице.Таким образом, запрос будет двухэтапным: 1) заполнить временную таблицу значениями INLIST, затем 2) выполнить запрос, объединяющий временную таблицу.

       MYTEMPTABLE
       autoincrementing id
       QueryID  [some value to identify the current query, perhaps a GUID]
       myvalue  one of the values in your in-list, string


      select * from foo
      inner join MYTEMPTABLE on foo.column = MYTEMPTABLE.myvalue and MYTEMPTABLE.QueryId = ?

      [cannot recall if JET allows ANDs in INNER JOIN as SQL Server does -- 
      if not, adjust syntax accordingly]

вместо

      select * from foo where foo.column IN (... )       

Таким образом, одна и та же таблица может обрабатывать несколько запросов одновременно, поскольку каждый запрос будет иметь уникальный идентификатор.Вы можете удалить строки в списке после того, как закончите с ними:

      DELETE FROM MYTEMPTABLE where QueryID = ?

PS Существует несколько способов обработки проблем с типом данных для объединения.Вы можете преобразовать строковое значение в MYTEMPTABLE, как требуется, или вы можете иметь несколько столбцов в MYTEMPTABLE с различными типами данных, вставляя и объединяя в правильный столбец:

       MYTEMPTABLE
       id
       queryid
       mytextvalue
       myintvalue
       mymoneyvalue
       etc
...