Подтвердить что ты не робот

Возвращенный набор записей закрыт (mysql DB, доступ к которому осуществляется через ODBC в VBA)

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

То, что я пытаюсь сделать, это вернуть результаты из ряда операторов SQL, а не пытаться объединить все это в одно массовое утверждение (которое, вероятно, будет работать, но будет трудно поддерживать/понимать). Я добавил флаг FLAG_MULTI_STATEMENTS = 67108864 в строку подключения, которая подавила ошибки синтаксиса драйвера.

Но теперь, когда я запускаю следующее:

queryDB.Open SQLquery, conn

recordset (queryDB) остается закрытым без видимой ошибки. Заявление sql можно найти здесь.

Я могу генерировать ошибки, которые не возвращаются в VBA, поэтому любая помощь здесь будет высоко оценена.

ПРИМЕЧАНИЕ. Операторы sql работают, так как я могу вставить этот оператор в phpMyAdmin и он возвращает правильные (непустые) результаты. Я не знаю, являются ли утверждения специфически проблемой, но, возможно, использование CREATE TEMPORARY TABLE ... или использование нескольких операторов в целом.

Также я предполагаю, что драйвер может пытаться вернуть результат для каждого оператора sql, а VBA только получает первое или что-то...

EDIT: инструкция sql для справок в будущем.

CREATE TEMPORARY TABLE tmpOrders AS
SELECT
o.customerName,
SUM(o.Sales) AS Sales,
SUM(TotalFobCost + TotalLandedCost + TotalLocalCost + TotalCmtCost) AS TotalCost,
YEAR(o.deliveryDate) AS YEAR,
MONTH(o.deliveryDate) AS MONTH
FROM devere_costing.orders_fixed_extras AS o
WHERE o.orderApproved = TRUE
AND o.orderCanceled = FALSE
AND o.deliveryDate BETWEEN '2014-01-01' AND '2014-03-31'
GROUP BY customerName, YEAR, MONTH
ORDER BY YEAR ASC, MONTH ASC, customerName ASC;

CREATE TEMPORARY TABLE tmpProj AS
SELECT p.customerName,
   IF(p.MONTH > 9, p.YEAR, p.YEAR - 1) AS TrueYear,
   1 + ((p.MONTH + 2) MOD 12) AS TrueMonth,
   SUM(p.actualSalesInvoiced) AS salesInvoiced,
   SUM(p.budget) AS budget
FROM devere_costing.sales_projection_data AS p
GROUP BY p.customerName, p.YEAR, p.MONTH
HAVING TrueYear BETWEEN YEAR('2014-01-01') AND YEAR('2014-03-31')
AND TrueMonth BETWEEN MONTH('2014-01-01') AND MONTH('2014-03-31');

CREATE TEMPORARY TABLE tmpLeft AS
SELECT
IF(o.customerName IS NULL, p.customerName, o.customerName) AS customerName,
p.budget AS TotalBudget,
o.Sales AS Sales,
p.salesInvoiced,
0 AS varianceToBudget,
o.TotalCost,
0 AS directMargin,
0 AS directMarginPercent,
IF(o.YEAR IS NULL, p.TrueYear, o.YEAR) AS YEAR,
IF(o.MONTH IS NULL, p.TrueMonth, o.MONTH) AS MONTH
FROM tmpOrders AS o
LEFT JOIN tmpProj AS p
ON (o.customerName = p.customerName
AND o.YEAR = p.TrueYear
AND o.MONTH = p.TrueMonth);

CREATE TEMPORARY TABLE tmpRight AS
SELECT
IF(o.customerName IS NULL, p.customerName, o.customerName) AS customerName,
p.budget AS TotalBudget,
o.Sales AS Sales,
p.salesInvoiced,
0 AS varianceToBudget,
o.TotalCost,
0 AS directMargin,
0 AS directMarginPercent,
IF(o.YEAR IS NULL, p.TrueYear, o.YEAR) AS YEAR,
IF(o.MONTH IS NULL, p.TrueMonth, o.MONTH) AS MONTH
FROM tmpOrders AS o
RIGHT JOIN tmpProj AS p
ON (o.customerName = p.customerName
AND o.YEAR = p.TrueYear
AND o.MONTH = p.TrueMonth);

(SELECT * FROM tmpLeft) UNION DISTINCT (SELECT * FROM tmpRight);

Я ответил на свой вопрос!

Тайная ложь здесь:

Итак, я был прав в том, что было возвращено более одного набора записей. Мне просто нужно было проходить через них, чтобы найти нужные мне данные. Коллекция не индексируется, поэтому вам нужно выполнить поиск по каждому из них. В моем случае каждый оператор sql не возвращает набор записей (поэтому мой набор записей оставался закрытым, когда я пытался его открыть). Единственным исключением является последняя инструкция sql, которая возвращает записи. Моя петля выглядит так:

Dim rs As ADODB.Recordset
Set rs = queryDB(Sql)

' Loop through returned recordsets to find the data
Do
    If Not rs Is Nothing Then
        If rs.State = adStateOpen Then
            ' we have an open recordset.  This means that the final select statement
            ' has returned this data.
            Exit Do
        Else
            ' Otherwise iterate through to the next recordset
            Set rs = rs.NextRecordset
        End If
    Else
        MsgBox "No recordset returned by sql statement"
        GoTo ExitCode
    End If
Loop
4b9b3361

Ответ 1

Ответ скопирован из вопроса:

Я ответил на свой вопрос!

Тайна лежит здесь:

Итак, я был прав в том, что было возвращено более одного набора записей. Мне просто нужно было проходить через них, чтобы найти нужные мне данные. Коллекция не индексируется, поэтому вам нужно выполнить поиск по каждому из них. В моем случае каждый оператор sql не возвращает набор записей (поэтому мой набор записей оставался закрытым, когда я пытался его открыть). Единственным исключением является последняя инструкция sql, которая возвращает записи. Моя петля выглядит так:

Dim rs As ADODB.Recordset
Set rs = queryDB(Sql)

' Loop through returned recordsets to find the data
Do
    If Not rs Is Nothing Then
        If rs.State = adStateOpen Then
            ' we have an open recordset.  This means that the final select statement
            ' has returned this data.
            Exit Do
        Else
            ' Otherwise iterate through to the next recordset
            Set rs = rs.NextRecordset
        End If
    Else
        MsgBox "No recordset returned by sql statement"
        GoTo ExitCode
    End If
Loop