我有以下问题,当我在过程中运行此代码时,从我的SQL COMPACT DATABASE(sdf)获取SQL时,它会给出一个错误“Object Already Open”。我怎样才能解决这个问题。以下是我的程序代码
Function GetSQL(sName: String; Var App: TApplication): String;
Var
Q: TADOQuery;
Begin
Q := TADOQuery.Create(App);
Q.ConnectionString := GetConnectionStringFromRegistry;
Q.Close;
Q.SQL.Text := 'SELECT * FROM SQLs WHERE Name = :sname';
Q.Parameters.ParamByName('sname').Value := sName;
Try
Q.Open;
If Q.RecordCount >= 1 Then
Begin
Q.First;
Result := Q['Query'];
Q.Close;
End;
Finally
Q.Free;
End;
End;
[这就是错误的样子] [这是我按Break时代码的样子]
答案 0 :(得分:2)
我唯一看到的可能是问题的是,如果没有返回任何行,您的代码会打开查询:
Q.Open;
Try
If Q.RecordCount >= 1 Then
Begin
Q.First;
Result := Q['Query'];
Q.Close; // If Q.RecordCount = 0 above, this line never executes
End;
Finally
Q.Free;
End;
将Q.Close
移到finally
内,以便随时调用:
Q.Open;
Try
If Q.RecordCount >= 1 Then
Begin
Q.First;
Result := Q['Query'];
End;
Finally
Q.Close; // This will always run, even if no rows are returned
Q.Free; // or if an exception occurs.
End;
另外,您应该使用参数化查询而不是连接文本,尤其是如果您多次运行相同的查询,唯一的更改是sName
的值。服务器足够智能,可以缓存已编译的查询,只替换参数值,这意味着您的代码执行速度更快,服务器负载更少。
Function GetSQL(sName: String; Var App: TApplication): String;
Var
Q: TADOQuery;
Begin
Q := TADOQuery.Create(App);
Q.ConnectionString := GetConnectionStringFromRegistry;
// I've even tried closing it first
Q.Close;
Q.SQL.Text := 'SELECT Query FROM SQLs WHERE Name = :sname';
Q.ParamByName('sname').AsString := sName;
Try
// Error occurs here
Q.Open;
//Q.Active := True;
If Q.RecordCount >= 1 Then
Begin
Q.First;
Result := Q['Query'];
End;
Finally
Q.Close;
Q.Free;
End;
End;
答案 1 :(得分:1)
感谢@ user582118提醒这个......
这实际上是SQL CE的OleDB提供程序中的错误。如果表中的nvarchar字段大于127个字符,并且您对该表执行了select查询,则会收到DB_E_OBJECTOPEN错误。