Ich greife mit Delphi über die nativen ADO-Objekte auf den SQL-Server (MSDE - lokal) zu und habe mir zu diesem Zweck eine Klasse u.a. mit folgender Methode für SQL-Abfragen geschrieben:
<PRE>
procedure TJMAdoExeQySp.ExecQry;
{Führt eine Abfrage auf dem SQL-Server aus
Setzt ggf. Parameter (wenn FWithPara = true)
Gibt ggf. Datenmenge zurück (wenn FResSet = true)
Property Done wird entsprechend gesetzt}
var i: smallint;
aCon: _Connection;
aCommand: _Command;
aRS: _Recordset;
vRows: OLEVariant;
begin
// ======
// Prolog
// ======
if not FDone then Exit;
gs_AdoErrorList.Clear; // Eigene Fehlerliste leeren
// =================================
// Verbindung vorbereiten und öffnen
// =================================
aCon := coConnection.Create; // Connection-Objekt
aCon.CursorLocation := adUseClient;
try
aCon.Open(FConstr,'','',adConnectUnspecified);
except
FDone := JMAdo_GetErrorsFromConObject(aCon);
end; // try except
if FDone then begin
// ==========================
// Command-Objekt vorbereiten
// ==========================
aCommand := CoCommand.Create;
with aCommand do begin
CommandType := adCmdText;
CommandText := FCommandText; // Abfragetext
// ====================
// Parameter einrichten
// ====================
if FWithPara then
// Input-Parameter erzeugen und mit Daten besetzen
for i := 0 to High(FParProps) do begin
Parameters.Append
(CreateParameter(FParProps[i].PN,FParProps[i].DT,
adParamInput,FParProps[i].FL,
EmptyParam));
// Ggf Precision und NumericScale setzen
if (FParProps[i].DT = adNumeric) or
(FParProps[i].DT = adDecimal) then begin
Parameters[i].Precision :=
FParProps[i].PR;
Parameters[i].NumericScale :=
FParProps[i].NS;
end; // if (FParProps[i].DT
end; // for i
// =========================================
// Command- mit Connenction-Objekt verbinden
// =========================================
try
Set_ActiveConnection(aCon);
except
FDone := JMAdo_GetErrorsFromConObject(aCon);
end; // try except
end; // with aCommand
if FDone then begin
// ============================
// Ggf. Parameterwerte zuweisen
// ============================
if FWithPara then
for i := 0 to High(FParValues) do
aCommand.Parameters[i].Value := FParValues[i];
// =========================================
// Ggf Recordset erzeugen und Daten versehen
// =========================================
if FResSet then begin
aRS := CoRecordset.Create;
aRS.CursorLocation := adUseClient;
end; // if aeprRes in FExeKindParaRes
// ==================
// Kommando ausführen
// ==================
try
if FResSet then
// wenn Datenmenge geliefert wird
// im Recordset-Objekt Datenmenge öffnen
aRS.Open(aCommand,EmptyParam,adOpenStatic,
adLockBatchOptimistic,adCmdUnspecified)
else // wenn keine Datenmenge geliefert wird
// Abfrage im Command-Objekt ausführen
aCommand.Execute(vRows,EmptyParam,
adExecuteNoRecords);
except
FDone := JMAdo_GetErrorsFromConObject(aCon);
end; // try except
// ==========================
// Ggf. Datenmenge übernehmen
// ==========================
if FDone and FResSet then GetAdoDataSet(aRS);
end; // if FDone
end; // if FDone
// ======
// Epilog
// ======
// Aufräumen
if FResSet then begin
if FDone then aRs.Close;
if aRS <> nil then aRS := nil;
end; // if aeprRes in FExeKindParaRes
if aCommand <> nil then aCommand := nil;
if FDone then aCon.Close;
aCon := nil;
end; // ExecQry
</PRE>
Die Routine baut die Verbindung zum Server mit einem Connenction-Objekt auf und erzeugt ggf. ein Command- und ein Recordset-Objekt. Flag-gesteuert werden ggf. Parameter zugewiesen und ggf. wird mit Recordset die Datenmenge abgeholt. Zuletzt wird alles wieder geschlossen und die Verbindung abgebaut.
Wird mit dieser Methode eine SQL-Afrage ausgeführt, erhalte ich meistens zunächst die Fehlermeldung
"Falsche Syntax in der Nähe von 1"
Native Error: 170
ADO-Fehler: -2147217900
SQL-Fehlercode: 42000
Die SQL-Abfragen waren bisher parameterlos.
Das merkwürdige ist: Wird die Abfrage unmittelbar wiederholt, ist alles ok. Das Verhalten ist reproduzierbar. Interessant ist auch, dass auch alles ok ist, wenn ich das Programm in Delphi starte und die Routine mit dem Debugger durchtackere. Liegt da evtl. ein Zeitproblem vor ????
Ich weiss mir jetzt keinen Rat mehr und wäre dankbar um einen solchen.
Mein PC: AMD-Prozessor, WindowsXp Prof, kein SP2, MSDE, Delphi7
Mit freundlichem Gruss
Hans Grigull
<PRE>
procedure TJMAdoExeQySp.ExecQry;
{Führt eine Abfrage auf dem SQL-Server aus
Setzt ggf. Parameter (wenn FWithPara = true)
Gibt ggf. Datenmenge zurück (wenn FResSet = true)
Property Done wird entsprechend gesetzt}
var i: smallint;
aCon: _Connection;
aCommand: _Command;
aRS: _Recordset;
vRows: OLEVariant;
begin
// ======
// Prolog
// ======
if not FDone then Exit;
gs_AdoErrorList.Clear; // Eigene Fehlerliste leeren
// =================================
// Verbindung vorbereiten und öffnen
// =================================
aCon := coConnection.Create; // Connection-Objekt
aCon.CursorLocation := adUseClient;
try
aCon.Open(FConstr,'','',adConnectUnspecified);
except
FDone := JMAdo_GetErrorsFromConObject(aCon);
end; // try except
if FDone then begin
// ==========================
// Command-Objekt vorbereiten
// ==========================
aCommand := CoCommand.Create;
with aCommand do begin
CommandType := adCmdText;
CommandText := FCommandText; // Abfragetext
// ====================
// Parameter einrichten
// ====================
if FWithPara then
// Input-Parameter erzeugen und mit Daten besetzen
for i := 0 to High(FParProps) do begin
Parameters.Append
(CreateParameter(FParProps[i].PN,FParProps[i].DT,
adParamInput,FParProps[i].FL,
EmptyParam));
// Ggf Precision und NumericScale setzen
if (FParProps[i].DT = adNumeric) or
(FParProps[i].DT = adDecimal) then begin
Parameters[i].Precision :=
FParProps[i].PR;
Parameters[i].NumericScale :=
FParProps[i].NS;
end; // if (FParProps[i].DT
end; // for i
// =========================================
// Command- mit Connenction-Objekt verbinden
// =========================================
try
Set_ActiveConnection(aCon);
except
FDone := JMAdo_GetErrorsFromConObject(aCon);
end; // try except
end; // with aCommand
if FDone then begin
// ============================
// Ggf. Parameterwerte zuweisen
// ============================
if FWithPara then
for i := 0 to High(FParValues) do
aCommand.Parameters[i].Value := FParValues[i];
// =========================================
// Ggf Recordset erzeugen und Daten versehen
// =========================================
if FResSet then begin
aRS := CoRecordset.Create;
aRS.CursorLocation := adUseClient;
end; // if aeprRes in FExeKindParaRes
// ==================
// Kommando ausführen
// ==================
try
if FResSet then
// wenn Datenmenge geliefert wird
// im Recordset-Objekt Datenmenge öffnen
aRS.Open(aCommand,EmptyParam,adOpenStatic,
adLockBatchOptimistic,adCmdUnspecified)
else // wenn keine Datenmenge geliefert wird
// Abfrage im Command-Objekt ausführen
aCommand.Execute(vRows,EmptyParam,
adExecuteNoRecords);
except
FDone := JMAdo_GetErrorsFromConObject(aCon);
end; // try except
// ==========================
// Ggf. Datenmenge übernehmen
// ==========================
if FDone and FResSet then GetAdoDataSet(aRS);
end; // if FDone
end; // if FDone
// ======
// Epilog
// ======
// Aufräumen
if FResSet then begin
if FDone then aRs.Close;
if aRS <> nil then aRS := nil;
end; // if aeprRes in FExeKindParaRes
if aCommand <> nil then aCommand := nil;
if FDone then aCon.Close;
aCon := nil;
end; // ExecQry
</PRE>
Die Routine baut die Verbindung zum Server mit einem Connenction-Objekt auf und erzeugt ggf. ein Command- und ein Recordset-Objekt. Flag-gesteuert werden ggf. Parameter zugewiesen und ggf. wird mit Recordset die Datenmenge abgeholt. Zuletzt wird alles wieder geschlossen und die Verbindung abgebaut.
Wird mit dieser Methode eine SQL-Afrage ausgeführt, erhalte ich meistens zunächst die Fehlermeldung
"Falsche Syntax in der Nähe von 1"
Native Error: 170
ADO-Fehler: -2147217900
SQL-Fehlercode: 42000
Die SQL-Abfragen waren bisher parameterlos.
Das merkwürdige ist: Wird die Abfrage unmittelbar wiederholt, ist alles ok. Das Verhalten ist reproduzierbar. Interessant ist auch, dass auch alles ok ist, wenn ich das Programm in Delphi starte und die Routine mit dem Debugger durchtackere. Liegt da evtl. ein Zeitproblem vor ????
Ich weiss mir jetzt keinen Rat mehr und wäre dankbar um einen solchen.
Mein PC: AMD-Prozessor, WindowsXp Prof, kein SP2, MSDE, Delphi7
Mit freundlichem Gruss
Hans Grigull
Comment