none
Unterschied bei ADO CursorLocation adUseClient und adUseServer Welche Strategie wählen, wenn die Anzahl der Datensätze unbekannt ist? RRS feed

  • Frage

  • Hallo zusammen,

    ich baue eine Verbindung zu einem MSSQL-Server2014 mittels ADO in Excel auf :

    strSQL = "SELECT COUNT(*) FROM [Test].[dbo].[TestTB]"
        Set objRecordsetAnz = CreateObject("ADODB.recordset")
        With objRecordsetAnz
            .ActiveConnection = objConnSQL
            .CursorLocation = adUseClient
            .CursorType = adOpenStatic
            .LockType = adLockOptimistic
            .Open = strSQL
        End With

    Als CursorLocation habe ich adUseClient gewählt. Offensichtl. befinden sich mehrere Mio Datensätze in der abgefragten Tabelle und es kommt zu einem Error.

    Bei ca. 10.000 Datensätzen läuft das einwandfrei.

    Welche CursorLocation sollte man wählen oder welche sonstige Strategien gibt es?

    Gruß Jürgen

    Donnerstag, 5. Januar 2017 16:21

Alle Antworten

  • Hallo Jürgen,

    ein SELECT COUNT sollte eigentlich nicht zu einem Problem führen.

    Poste daher bitte mal die exakte und vollständige Fehlermeldung.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Donnerstag, 5. Januar 2017 16:34
    Moderator
  • Hi Jürgen,
    mit dem clientseitigen Cursor werden alle Änderungen im Programm im Datenpuffer des Programms verwaltet und erst beim Update zurück in die Datenbank geschrieben. Beim serverseitigen Cursor wird jede Änderung in einem Datensatz sofort in den Datenbankserver zur Verwaltung übergeben.

    Sehr viele Datensätze sollten aus Gründen der Ressourcennutzung und Verarbeitungsgeschwindigkeit nicht Anwenderprogramm gepuffert werden. Durch Nutzung der Where-Klausel in der SQL Anweisung sollte man die Anzahl der im Anwenderprogramm zu verarbeitenden Datensätze einschränken, wobei ein Richtwert von maximal 2000 bis 5000 Datensätze angestrebt werden sollte. Zusätzlich sollte man durch Angabe der Felder (anstelle *) die Anzahl der zu ladenden "Spalten" einschränken, so dass nur die für den konkreten abzubildenden Prozess Daten in den Puffer des Anwendungsprogramms geladen werden.


    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP)
    Meine Homepage mit Tipps und Tricks

    Donnerstag, 5. Januar 2017 16:37
  • Hallo Jürgen,

    ob adUseClient oder adUseServer ist bei COUNT Abfrage ohne Belang. Da die Datensätze auf Serverseite real gezählt werden müssen, spielt der CommandTimeout (Standard 30 Sekunden) bei großen Mengen eine Rolle. Da man das Ergebnis nicht verändern kann, sollte man als LockType adLockReadOnly verwenden.

    Die Tabelle sollte einen Index haben, damit die Zählerei schneller von statten geht. Hinzu kommen können Sperren, die die Abfrage blockieren. Diese kann man ggf. mit über eine WITH (NOLOCK) Option umgehen, womit jedoch das Ergebnis mehr eine Schätzung wird (wobei man die Anzahl immer als veränderlich ansehen sollte).

    Gruß Elmar

    Donnerstag, 5. Januar 2017 20:38
  • Hallo zusammen,

    danke an alle für eure Anmerkungen.

    Das Problem lag zunächst bei der Benennung der Tabelle hinter dem FROM "[TestDB].[dbo].[TestTB]". Da wurde ein falscher Parameter im VBA-Code übergeben, also jetzt alles gut und die Anzahl wird richtig ermittelt.

    Aber jetzt taucht danach ein anderes Problem auf:
    Ich habe danach eine SQL-Abfrage gestartet, mit der alle Duplikate gesucht werden sollen. Die Tabelle hat gut 7Mio Datensätze und 40 Spalten.

    Paramter
    CommandTimeout = 0 für die Connection gesetzt und
    .CursorLocation = adUseClient  
    .LockType = adLockReadOnly
    Die SELECT COUNT([idTest])... ist auch gesetzt
          

    Die Routine hängt sich komplett auf mit dem Excel-Fehler: "Zu wenig Arbeitsspeicher".

    Welche Strategie muss hier gefahren werden? Etwa "adUseServer" wählen?

    Die Anwendung ist eine SingleUserApp, d.h. Änderungen am Datenbestand sowohl im Client als auch auf dem Server finden während der Routine nicht statt.

    Gruß Jürgen

    Freitag, 6. Januar 2017 13:27
  • Hallo Jürgen,

    auch wenn Du mit dem SQL Server zugreifst, bleibt Excel bloß Excel.

    Ich würde die Tabelle in den SQL Server importieren und alle weiteren Schritte dort ausführen.


    Einen schönen Tag noch, Christoph -- Data Platform MVP - http://www.insidesql.org/blogs/cmu

    Montag, 16. Januar 2017 07:13
    Beantworter