为什么特定 SQL 的记录数为 -1?

Why would specific SQL have a recordcount of -1?

我找到了一些代码。记录集打开如下...

rs.open sql, db, 3, 3, 1

加上下面的SQL,记录集的RecordCount属性是正确的。

SELECT client.id, 
       client.NAME, 
       postcode, 
       locationx, 
       locationy, 
       NULL     AS blacklisted, 
       ' ' AS distance 
FROM   client 
       LEFT JOIN county 
              ON client.county = county.id 
WHERE  hidden = 0 
       AND client.NAME LIKE '%' 
       AND ( address LIKE '%%' 
              OR county.NAME LIKE '%%' 
              OR postcode LIKE '%%' 
              OR phone LIKE '%%' 
              OR fax LIKE '%%' ) 
ORDER  BY client.NAME 

对于下面的野兽,RecordCount 属性 是 -1。

SELECT          booking.id, 
                booking.site, 
                site.NAME, 
                booking.client, 
                client.NAME AS clientname, 
                booking.confirmed, 
                Count(appointment.id)                   AS apps, 
                Sum(Cast(appointment.confirmed AS INT)) AS conf, 
                dates.[date]                            AS startdate, 
                h.hoursfull, 
                h.hours, 
                d.overdue, 
                e.soon 
FROM            booking 
LEFT OUTER JOIN site 
ON              booking.site = site.id 
LEFT OUTER JOIN dates 
ON              booking.id = dates.booking 
LEFT OUTER JOIN appointment 
ON              dates.id = appointment.[date] 
LEFT OUTER JOIN client 
ON              booking.client = client.id 
LEFT OUTER JOIN 
                ( 
                SELECT          booking, 
                                Sum(dates.hours)    AS hours, 
                                Sum(apps1.hourssum) AS hoursfull 
                FROM            dates 
                LEFT OUTER JOIN 
                                ( 
                                            SELECT   [date], 
                                                    Sum(hours) AS hourssum 
                                            FROM     appointment 
                                            GROUP BY [date] ) AS apps1 
                ON              dates.id = apps1.[date] 
                GROUP BY        booking ) h 
ON              booking.id = h.booking 
LEFT OUTER JOIN 
                ( 
                       SELECT 1 AS overdue) d 
ON              dates.[date] <= Getdate() 
LEFT OUTER JOIN 
                ( 
                       SELECT 1 AS soon) e 
ON              dates.[date] <= Dateadd(hh, 48, Getdate()) 
LEFT OUTER JOIN 
                ( 
            SELECT DISTINCT a.booking 
            FROM            ( 
                                            SELECT          dates.booking, 
                                                            Sum(apps2.hourssum) AS filled,
                                                            sum(dates.hours)   AS hours
                                            FROM            dates 
                                            LEFT OUTER JOIN 
                                                            ( 
                                                                        SELECT   [date],
                                                                                sum(hours) AS hourssum
                                                                        FROM     appointment
                                                                        GROUP BY [date] ) AS apps2
                                            ON              dates.id = apps2.[date] 
                                            GROUP BY        dates.booking )a 
            WHERE           ( 
                                            filled < hours) 
            OR              ( 
                                            filled IS NULL) )b 
ON              b.booking = booking.id 
WHERE           ( 
                                booking.hidden = 0) 
AND             booking.client = 2543 
AND             booking.confirmed = 1 
AND             ((( 
                SELECT TOP 1 
                    dates.id 
                FROM            dates 
                LEFT OUTER JOIN appointment 
                ON              dates.id = appointment.[date] 
                WHERE           ( 
                                dates.booking = booking.id)
                GROUP BY        dates.id, 
                                dates.booking 
                ORDER BY        dates.booking) = dates.id)
                OR              dates.id IS NULL) 
GROUP BY        booking.id, 
                booking.site, 
                site.NAME, 
                booking.confirmed, 
                dates.[date], 
                booking.client, 
                client.NAME, 
                h.hoursfull, 
                h.hours, 
                d.overdue, 
                e.soon 
ORDER BY        startdate

我可以通过在同一调用 "open" 之前切换 SQL 来重复此行为。

如果您使用的是 ADO recordset, which I suspect you are, you must use a static or keyset cursor type, if you want to access the RecordCount property

取自 MSDN

The cursor type of the Recordset object affects whether the number of records can be determined. The RecordCount property will return -1 for a forward-only cursor; the actual count for a static or keyset cursor; and either -1 or the actual count for a dynamic cursor, depending on the data source.

编辑

如果我完整阅读了您的问题,将会有所帮助!在更大更复杂的查询中,即使使用正确的游标类型,RecordCount 也有可能达到 return -1。发生这种情况的原因有很多。一个例子是记录集在您开始使用时仍在填充。尝试跳转到最后一条记录,然后查询记录数。

我更改了打开记录集的代码...

rs.open sql, db, 3, 3, 1

到...

rs.open sql, db, adOpenStatic, adLockReadOnly, adCmdText

非常感谢 this 站点。