Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 多记录集问题_Sql_Sql Server_Vba_Ado - Fatal编程技术网

Sql 多记录集问题

Sql 多记录集问题,sql,sql-server,vba,ado,Sql,Sql Server,Vba,Ado,我有下面的SQL脚本,它是在SQLServer2000数据库上使用ADO从ExcelVBA运行的 我遇到的问题是,尽管脚本中只有一个SELECT语句,但在执行.Open方法时,有时会收到三个记录集。我说,有时就像在OCCasion和其他“并行”数据库上一样,我只收到一个记录集 我知道所有关于.NextRecordset的方法等,但我试图理解为什么有时我会得到三个记录集,而有时我只收到一个。我很快将运行一个SQL跟踪,看看这是否会引发任何想法,但像往常一样,任何帮助或建议都将不胜感激 SET NO

我有下面的SQL脚本,它是在SQLServer2000数据库上使用ADO从ExcelVBA运行的

我遇到的问题是,尽管脚本中只有一个SELECT语句,但在执行.Open方法时,有时会收到三个记录集。我说,有时就像在OCCasion和其他“并行”数据库上一样,我只收到一个记录集

我知道所有关于.NextRecordset的方法等,但我试图理解为什么有时我会得到三个记录集,而有时我只收到一个。我很快将运行一个SQL跟踪,看看这是否会引发任何想法,但像往常一样,任何帮助或建议都将不胜感激

SET NOCOUNT ON
DECLARE @RunDate VARCHAR(8)

SET @RunDate = CONVERT(VARCHAR(8), DATEADD(d, -1 * 1, GETDATE()), 112)

IF OBJECT_ID('tempdb..#ActiveOrders') IS NOT NULL DROP TABLE #ActiveOrders
IF OBJECT_ID('tempdb..#ApplicableOrders') IS NOT NULL DROP TABLE #ApplicableOrders
IF OBJECT_ID('tempdb..#FilterOut') IS NOT NULL DROP TABLE #FilterOut

/*Temp table created as it has a self-join in the below query */
CREATE TABLE #ActiveOrders(
    order_id VARCHAR(30) 
    , instrument_id VARCHAR(30) 
    , side CHAR(1)
    )

CREATE INDEX idx_ActiveOrders_orderId ON #ActiveOrders(order_id)

/*Build dataset of all orders which have had activity on the run date or are in an Open status. Ignoring Program Trades.*/
INSERT INTO #ActiveOrders 
SELECT o1.order_id COLLATE Latin1_General_CI_AS
        , o1.instrument_id
        , o1.side
FROM orders o1
INNER JOIN desk d1 ON d1.desk_id = o1.investment_desk
INNER JOIN (SELECT o0.order_id
            FROM orders o0
            WHERE ((LEFT(o0.added_datetime, 8) = @RunDate
                    OR LEFT(o0.approved_datetime, 8) = @RunDate)
                    OR (LEFT(o0.added_datetime, 8) <= @RunDate
                    AND o0.summary_status IN (1, 2, 3, 5, 8, 9))) /*Approved, Assigned, Acknowledged, Working, Partial, WorkingPartial*/
            UNION
            (SELECT r0.order_id
            FROM releases r0
            WHERE LEFT(r0.added_datetime, 8) = @RunDate)
            UNION
            (SELECT e0.order_id
            FROM executions e0
            WHERE LEFT(e0.execution_datetime, 8) = @RunDate
                    OR LEFT(e0.allocated_datetime, 8) = @RunDate)
            ) t1 ON o1.order_id = t1.order_id
WHERE d1.location_id = 'LDEQ'       
        AND o1.summary_status <> 4
        AND o1.list_id IS NULL /*Ignore program trades*/

/*This is now the actual dataset we are interested in.
This is everything which could be a contender for aggregation.*/
CREATE TABLE #ApplicableOrders(
    order_id VARCHAR(30)
    , instrument_id VARCHAR(30)
    , side CHAR(1)
    , approved_datetime DATETIME
    , acknowledged_datetime DATETIME
    , last_allocation_datetime DATETIME
    , latest_status INT
    , merged_orders VARCHAR(500)
    , dealer VARCHAR(100)
    , manager VARCHAR(100)
    , limit_price FLOAT
    , original_qty FLOAT
    , executed_qty FLOAT
    , trader_instruction TEXT
    , dealer_note TEXT
    )

CREATE INDEX idx_ApplicableOrders_orderId ON #ApplicableOrders(order_id)
CREATE INDEX idx_ApplicableOrders_lastAllocation ON #ApplicableOrders(last_allocation_datetime)
CREATE INDEX idx_ApplicableOrders_approved ON #ApplicableOrders(approved_datetime)

/*All orders from #ActiveOrders where there are two or more orders which are for the same instrument and in the same direction.*/
INSERT INTO #ApplicableOrders 
SELECT o.order_id
        , o.instrument_id
        , o.side
        , dbo.mglz_datetime(o.approved_datetime) 
        , dbo.mglz_datetime(o.ack_datetime) 
        , MAX(dbo.mglz_datetime(e.allocated_datetime)) "Last Allocation DateTime"
        , o.summary_status
        , o.merged_orders
        , o.ack_id
        , o.approver_id
        , o.limit_price
        , o.original_qty 
        , o.executed_qty_at
        , CONVERT(VARCHAR(900), o.trader_instruction)
        , CONVERT(VARCHAR(900), o.dealer_note)
FROM orders o
        INNER JOIN #ActiveOrders t ON o.order_id = t.order_id COLLATE Latin1_General_CI_AS
        INNER JOIN #ActiveOrders s ON s.order_id <> o.order_id COLLATE Latin1_General_CI_AS
                                        AND s.instrument_id = o.instrument_id COLLATE Latin1_General_CI_AS
                                        AND s.side = o.side COLLATE Latin1_General_CI_AS
        LEFT JOIN executions e ON e.order_id = o.order_id
GROUP BY o.order_id
        , o.instrument_id
        , o.side
        , o.approved_datetime
        , o.ack_datetime
        , o.summary_status
        , o.merged_orders
        , o.ack_id
        , o.approver_id
        , o.limit_price
        , o.original_qty 
        , o.executed_qty_at
        , CONVERT(VARCHAR(900), o.trader_instruction)
        , CONVERT(VARCHAR(900), o.dealer_note)

/*Filter out any orders where Order2.Approved_Date > Order1.Last_Release_Date AND Order1.Is_Complete
Order1 is defined as the order which was approved first.*/
SELECT t1.*
INTO #FilterOut
FROM #ApplicableOrders t1
WHERE EXISTS (SELECT 1
                FROM
                    (SELECT order2.order_id
                    FROM (SELECT b.order_id
                                    , b.instrument_id
                                    , b.side
                                    , b.approved_datetime
                                    , b.last_allocation_datetime
                                    , b.latest_status
                                    , b.executed_qty
                                    , b.original_qty
                            FROM #ApplicableOrders b
                            WHERE b.approved_datetime = (SELECT MIN(b1.approved_datetime) FirstApproval
                                                        FROM #ApplicableOrders b1
                                                        WHERE b1.instrument_id = b.instrument_id
                                                            AND b1.side = b.side)
                        ) order1
                    INNER JOIN 
                        (SELECT c.order_id
                                , c.instrument_id
                                , c.side
                                , c.approved_datetime
                            FROM #ApplicableOrders c
                            WHERE c.approved_datetime > (SELECT MIN(c1.approved_datetime) FirstApproval
                                                        FROM #ApplicableOrders c1
                                                        WHERE c1.instrument_id = c.instrument_id
                                                            AND c1.side = c.side)
                        ) order2
                    ON order1.instrument_id = order2.instrument_id
                        AND order1.side = order2.side
                        AND order2.approved_datetime > order1.last_allocation_datetime
                        AND (order1.latest_status = 6 OR order1.executed_qty = order1.original_qty)) filter1 
                WHERE t1.order_id = filter1.order_id)

/*Filter out any orders where Order2.Acknowledged_Date > Order1.Last_Allocation_Date.*/
INSERT INTO #FilterOut
    SELECT t1.*
    FROM #ApplicableOrders t1
    WHERE EXISTS (SELECT 1
                    FROM
                        (SELECT order2.order_id
                        FROM (SELECT b.order_id
                                    , b.instrument_id
                                    , b.side
                                    , b.approved_datetime
                                    , b.last_allocation_datetime
                            FROM #ApplicableOrders b
                            WHERE b.approved_datetime = (SELECT MIN(b1.approved_datetime) FirstApproval
                                                        FROM #ApplicableOrders b1
                                                        WHERE b1.instrument_id = b.instrument_id
                                                            AND b1.side = b.side)
                            ) order1
                        INNER JOIN 
                            (SELECT c.order_id
                                    , c.instrument_id
                                    , c.side
                                    , c.approved_datetime
                                    , c.acknowledged_datetime
                                FROM #ApplicableOrders c
                                WHERE c.approved_datetime > (SELECT MIN(c1.approved_datetime) FirstApproval
                                                            FROM #ApplicableOrders c1
                                                            WHERE c1.instrument_id = c.instrument_id
                                                                AND c1.side = c.side)
                            ) order2
                        ON order1.instrument_id = order2.instrument_id
                            AND order1.side = order2.side
                            AND order2.acknowledged_datetime > order1.last_allocation_datetime) filter2 
                    WHERE t1.order_id = filter2.order_id)
    AND NOT EXISTS (SELECT 1
                    FROM #FilterOut a1
                    WHERE a1.order_id = t1.order_id)

/*Filter any 'single' orders. I.e. all 'matching' orders have been excluded so the instrument/direction combination is not applicable for Aggregation.*/
INSERT INTO #FilterOut
    SELECT t1.*
    FROM #ApplicableOrders t1 INNER JOIN (SELECT DISTINCT t.instrument_id
                                                            , t.side
                                            FROM #ApplicableOrders t
                                            INNER JOIN #FilterOut a ON t.instrument_id = a.instrument_id 
                                                                                AND t.side = a.side
                                            GROUP BY t.instrument_id
                                                    , t.side
                                            HAVING COUNT(t.instrument_id) > 1) t2 ON t1.instrument_id = t2.instrument_id 
                                                                                        AND t1.side = t2.side
    WHERE NOT EXISTS (SELECT 1
                        FROM #FilterOut a1
                        WHERE a1.order_id = t1.order_id)

/*Final Report*/
/*A list of all orders where aggregation could have possibly occurred but didn't.*/
SELECT t1.order_id "Order ID"
        , i.name "Name"
        , t1.side "B/S"
        , userDealer.short_name "Dlr"
        , userManager.short_name "FM"
        , t1.limit_price "Limit"
        , t1.approved_datetime "Order Approved"
        , t1.acknowledged_datetime "Order Acknowledged"
        , t1.last_allocation_datetime "Last Execution"
        , t1.merged_orders "Merged Orders"
        , m.description "Status"
        , t1.dealer_note "Dealer Note"
        , t1.trader_instruction "Trader Instruction"
FROM #ApplicableOrders t1 
    INNER JOIN instrument i ON t1.instrument_id = i.instrument_id COLLATE Latin1_General_CI_AS
    INNER JOIN mnemonics m ON t1.latest_status = m.value AND m.attribute = 'order_summary_status'
    LEFT JOIN users userDealer ON userDealer.user_id = t1.dealer COLLATE Latin1_General_CI_AS
    LEFT JOIN users userManager ON userManager.user_id = t1.manager COLLATE Latin1_General_CI_AS
WHERE NOT EXISTS (SELECT 1
                    FROM #FilterOut t2 
                    WHERE t1.order_id = t2.order_id)
ORDER BY t1.name
        , t1.side
        , t1.approved_datetime

IF OBJECT_ID('tempdb..#ActiveOrders') IS NOT NULL DROP TABLE #ActiveOrders
IF OBJECT_ID('tempdb..#ApplicableOrders') IS NOT NULL DROP TABLE #ApplicableOrders
IF OBJECT_ID('tempdb..#FilterOut') IS NOT NULL DROP TABLE #FilterOut

我会在临时表的末尾添加一个同位素列虚拟列,这样当您看到这三个记录集时,您就可以查询列名称以查看它们来自何处。当您从概要文件中获取SQL并直接在SSMS中运行时会发生什么?你只得到一个结果集吗?

我终于发现了问题,并认为我会向你汇报。问题在于脚本中的两个聚合函数中存在空值。这只是偶尔发生的原因,因为数据在不断变化

尽管SQL Server以“静默”方式处理该问题,但它确实会生成ADO视为记录集的警告,尽管在我的案例中,这些记录集可能都是关闭的,因此无法实际查看它们包含的内容或生成它们的内容

我没有使用ISNULL逻辑重新编写SQL脚本,而是选择只包含

SET ANSI_WARNINGS OFF 
脚本顶部的语句。这样可以防止报告警告,因此ADO不会生成这些额外的、不需要的记录集


失望的是,我没有早点发现这一点,但至少我学到了一些新东西

我应该补充一点,当我收到3个记录集时,前两个记录集处于关闭状态,表明没有要返回的记录。在使用SQL跟踪遇到死胡同并使用SQL之后,我认为问题似乎在于存在的两个选择1…感谢您的建议,但返回的三个记录集中有两个处于关闭状态,因此我无法对它们做任何处理,这就是为什么我一直在努力确定导致它们的原因。在SSMS中运行时,我似乎只返回一个记录集。我确信问题在于WHERE EXISTS语句,因为我有两个(它们是SELECT语句),但不幸的是,(目前)问题已经自行解决,所以我无法证明。一旦我知道了任何一种方法,我会发布我的结果。