2009-07-15 8 views
2

[Update: Die Abfrage funktioniert, wenn ich in den Parametern fest codiere - so hat es mit dem zu tun So füge ich Parameter zu der Abfrage hinzu]MS Access-Fehler: Die SELECT-Anweisung enthält ein reserviertes Wort oder einen Argumentnamen, der falsch geschrieben oder fehlt, oder die Interpunktion ist falsch

Für das Leben von mir kann ich nicht herausfinden, was das Problem hier ist.

Hier wird die Anfrage an die DataReader- weitergegeben werden:

SELECT * FROM (SELECT TOP ? StartDate, [ID] FROM 
    (SELECT TOP ? StartDate, [ID] FROM Story 
    ORDER BY StartDate DESC, [ID] DESC) AS foo 
    ORDER BY StartDate ASC, [ID] ASC) AS bar 
    INNER JOIN Story AS t ON bar.ID = t.ID 
    ORDER BY bar.StartDate DESC, bar.[ID] DESC 

Die Parameter in der folgenden Reihenfolge hinzugefügt:

var pNumToRetrieve = new OleDbParameter("", OleDbType.Integer) {Value = numToGet}; 
var pResultSet = new OleDbParameter("", OleDbType.Integer) {Value = resultSet}; 

_cmd.Parameters.Add(pNumToRetrieve); 
_cmd.Parameters.Add(pResultSet); 

Wenn ich diese Abfrage in dem Zugang direkt eingeben es ganz gut funktioniert. Wenn ich die Abfrage von ASP.NET ausführe, erhalte ich jedoch die folgende Fehlermeldung:

Die SELECT-Anweisung enthält ein reserviertes Wort oder einen Argumentnamen, der falsch geschrieben oder fehlt, oder die Interpunktion ist falsch.

Was mache ich falsch?

Danke,

Adam

+0

Das Problem besteht darin, die Zeichenfolge in ASP.NET auszuführen. Das benötigte Tag und die anzuwendende Fähigkeit wären also ASP.NET. ??? – Smandoli

+0

Könnten Sie das weiter ausführen? Die Abfrage, die ich oben eingefügt habe, stammt aus dem Debugger in asp.net - das ist der genaue Wert/Zeichenfolge, die übergeben wird. – adamisnt

+0

Ich denke, sie meinten, dass Ihre Frage mit ASP.NET und nicht mit SQL getaggt sein sollte. Aus Ihrer akzeptierten Antwort geht jedoch hervor, dass dies nicht der Fall ist. – nekomatic

Antwort

6

Die N in TOP N-Abfragen in Jet SQL können nicht parametriert werden, period. Sie müssen Ihre SQL-Zeichenfolge im laufenden Betrieb schreiben, um eine Variable N zu erhalten. Dies bedeutet entweder, dass Sie kein gespeichertes QueryDef verwenden können oder dass Sie das SQL von QueryDef bearbeiten müssen und es vor der Verwendung speichern müssen.

+0

+1. Guter Fang. Ich war so dumm, dass ich diese Abfrage nicht zuerst in Access versuchte, um zu sehen, ob es funktioniert :) – shahkalpesh

+0

Nun ich schätze das erklärt es dann: P Danke für die Antwort! Kennen Sie eine gute Ressource, die mir helfen könnte, Access-Abfragen in ASP.NET schneller auszuführen - insbesondere parametrisierte Abfragen über ASP.NET/ADO zu übergeben? Ich stoße auch auf Probleme mit parametrisierten BETWEEN-Abfragen auf Daten. Danke noch einmal! - Adam – adamisnt

+0

"Sie müssen Ihre SQL-Zeichenfolge im laufenden Betrieb schreiben, um eine Variable N zu bekommen" - nun, Sie könnten es mit einem anderen Konstrukt neu schreiben, z. eine korrelierte Unterabfrage – onedaywhen

0

Ich stelle fest, dass nicht alle Ihre ID-Spalten um sie eckigen Klammern haben. Das könnte es sein, aber es ist schon eine Weile her, seit ich mit Access gespielt habe, damit jemand anderes eine bessere Antwort hat.

EDIT:

Wie Sie kein Glück gehabt habe, so weit werde ich eine andere Vermutung versuchen. Könnten Sie versuchen, das "*" zu ändern, um stattdessen explizit die gewünschten Spalten zu benennen?

FINAL EDIT:

Das letzte Stück der Rat, den ich zu bieten haben ist die Abfrage mit einer sehr einfachen Version von sich selbst zu ersetzen, die keine Ergebnisse liefert. Dann geben Sie es einen Test, wenn es fehlschlägt, muss es der Parameter-Code sein, der fehlschlägt, wenn nicht, dann ist es etwas in der Komplexität der Abfrage. Wenn Sie die Abfrage schrittweise rekonstruieren, sollten Sie den Fehlerpunkt erkennen können. Sorry, ich kann nicht mehr Hilfe sein.

+0

Hallo Chris, Ich habe die Klammern nur hinzugefügt, um sicherzustellen, dass ID nicht ein reserviertes Wort in Access war. Das gleiche Ergebnis ohne sie. Dank - Adam – adamisnt

+0

Macht nichts. Hoffe, eine der anderen Antworten hilft –

+0

Gleiches Ergebnis wie zuvor. Danke für deine Hilfe, Chris. – adamisnt

0

Ist es, dass die pResultSet Parameter als OleDbTypeInteger eingegeben wird?

+0

Hallo Carl, ich habe den Typ im Rahmen meiner Fehlerbehebung hinzugefügt. Das Entfernen des Typparameters und das Übergeben des Werts als ein generisches Objekt führt zu denselben Ergebnissen. Danke für Ihre Hilfe. – adamisnt

0

Gefällt es die Reihenfolge von in den Unterabfragen? Das wird in SqlServer nicht unterstützt.

Edit: Mein Fehler, habe ich die Spitze verpasst?

+0

Hallo sgmoore, Die Abfrage ist eine, die ich bei http://www.codeproject.com/KB/aspnet/paging_various_databases.aspx für Paging-Ergebnisse gefunden habe. Wie gesagt, die Eingabe der Abfrage direkt in der SQL-Ansicht in Access funktioniert einwandfrei. – adamisnt

+0

Wie generieren Sie die Befehlszeichenfolge? Wenn Sie mehrere Zeichenfolgen zusammenfügen, fehlt möglicherweise ein Leerzeichen am Ende einer Zeile. – sgmoore

+0

Ich angehängt Strings - Allerdings habe ich in den Parameterwerten fest und die Abfrage funktioniert. Ich vermute daher, dass es ein Problem bei der Art und Weise gibt, wie ich Parameter hinzufüge/deklariere. Ich kann das Problem nicht finden! Argggh .. – adamisnt

0

Sehen Sie, wenn das Ändern der Abfrage auf diese Weise hilft.

PARAMETERS numToGet number, rowsToGet numeric; 
SELECT * FROM (SELECT TOP numToGet StartDate, [ID] FROM 
    (SELECT TOP rowsToGet StartDate, [ID] FROM Story 
    ORDER BY StartDate DESC, [ID] DESC) AS foo 
    ORDER BY StartDate ASC, [ID] ASC) AS bar 
    INNER JOIN Story AS t ON bar.ID = t.ID 
    ORDER BY bar.StartDate DESC, bar.[ID] DESC 

EDIT: Was ist der Wert, der mit diesen 2 Parametern übergeben wird? Sind beide Zahlen?

+0

Hallo shahkalpesh, Ich bekomme das gleiche Ergebnis mit Ihrer Abfrage. Danke - Adam – adamisnt

+0

Ja, ich bin 10 und 20, in dieser Reihenfolge übergeben – adamisnt

+0

Könnten Sie den Parameter beim Erstellen sie, mit der obigen Abfrage? var pNumToRetrieve = new OleDbParameter ("numToGet", OleDbType.Integer) und benenne auch den 2. Parameter. Funktioniert es? – shahkalpesh

2

Erwägen Sie das Umschreiben von TOP N Konstrukten mit korrelierten Unterabfragen.

Hier ist ein einfaches Beispiel. Betrachten Sie eine Tabelle namens Sequence mit einer Spalte (seq) von unique INTEGER s (eine Standard-SQL-Hilfstabelle, die in unzähligen Situationen nützlich ist - jede Datenbank sollte eine!)

Beide Abfragen geben zwei die höchsten Werte für zurück f:

1)

SELECT TOP 2 seq 
    FROM SEQUENCE 
ORDER 
    BY seq DESC; 

Vorteile: Der Access-Datenbank-Engine führt relativ gut diese (wie Sie für proprietäre Syntax erwarten würden). Nachteile: Proprietäre Syntax daher schlecht für die Portabilität. Das N (wie in TOP N) kann nicht parametrisiert werden. Für mich ist die Verwendung DESC in ORDER BY, um die höchsten Werte zurückzugeben, kontraintuitiv.

2)

SELECT S1.seq 
    FROM SEQUENCE AS S1 
WHERE 2 >= (    
      SELECT COUNT(*)   
       FROM SEQUENCE AS S2  
      WHERE S2.seq >= S1.seq 
      ); 

Pros: Standard-SQL-Syntax daher gut für die Portabilität. Das N kann parametrisiert werden. Nachteile: Die Access-Datenbank-Engine optimiert korrelierte Unterabfragen nicht sehr gut, daher wird die Leistung mit der Anzahl der Zeilen in der Tabelle verringert (wie immer bei Leistungsproblemen müssen Sie sie testen). Einige SQL-Codierer finden eine korrelierte Unterabfrage schwer zu verstehen und haben daher möglicherweise Wartungsprobleme.

+0

Ich glaube, Sie haben einen Fehler: für "SELECT seq AS S1" meinen Sie "SELECT seq". –

+0

Guter Ort! Code ausgeführt, OK, obwohl;) Jetzt korrigiert. – onedaywhen

+0

Danke onedaywhen - es ist schön zu wissen, dass wenn ich * eine parametrisierte Abfrage verwenden muss, kann ich es so machen. Obwohl - das scheint ein bisschen schwieriger für meine sql/db Ignorant zu verstehen. Ich habe deine Frage abgestimmt - danke für deine Hilfe. --Adam – adamisnt

Verwandte Themen