数据库错误 - 未从查询返回游标

时间:2014-01-28 09:07:23

标签: sql sqlite delphi delphi-xe4

“游标未从查询返回”出现问题,并找到了一个基本上再次重新打开查询的解决方案:

procedure TForm2.AdvGlowButton1Click(Sender: TObject);
begin
with ClientdataSet1 do
begin
Close;
CommandText :='';
CommandText :='INSERT INTO TLOG (LOKACIJA_ID,OPOMBA) VALUES (:a1,:a2)';
Params.ParamByName('a1').Value :=  Form3.ClientDataSet4.FieldByName('LOKACIJA_ID').AsString;
Params.ParamByName('a2').Value := cxMemo1.Text;
Execute;
CommandText :='';
CommandText :='SELECT * FROM TLOG WHERE LOKACIJA_ID =:a1';
Params.ParamByName('a1').Value := Form3.ClientDataSet4.FieldByName('LOKACIJA_ID').AsString;
Open;
end;

现在,我想知道这是否是正确的方法还是有另一种解决此错误的方法?如果我在第一次执行后尝试打开数据集(删除其余的),我会得到上面提到的错误。这是应该运作的方式吗?这是一个datasnap客户端 - 服务器应用程序,sqlite作为后端数据库。

编辑: 带有运行此查询的dataset1的表单使用另一种形式(form3),即Form3.DSProviderConnection1连接到服务器。在ServerMethodsUnit1中的服务器端 我有一个DatasetProvider8链接到SQLQuery7(在我的查询的SQL中:select * from TLOG)。我想我可以用一个表替换服务器上的这个查询。现在,我在FormShow上做的是这样:

procedure TForm2.FormShow(Sender: TObject);
begin
with ClientdataSet1 do
begin
ClientdataSet1.Close;
ClientdataSet1.CommandText :='';
ClientdataSet1.CommandText :='SELECT * FROM TLOG WHERE LOKACIJA_ID =:a1';
ClientDataSet1.Params.ParamByName('a1').Value := Form3.ClientDataSet4.FieldByName('LOKACIJA_ID').AsString;
ClientDataSet1.Open;
end; 

我根据位置提取记录。所以现在用户只能看到他在网格中所在位置的记录。如果我没有弄错,如果用户添加或更改记录,首先必须插入数据,然后再以与提取相同的方式再次显示。或没有 ?或者用表替换该服务器查询并使用过滤器(location_id)显示表本身更好,这样我就可以运行插入查询并只调用表刷新?

1 个答案:

答案 0 :(得分:1)

您有很多选择。最合适的将取决于您的环境和要求的细节。我不确定你得到了什么因为你引用了ClientDataSet,这意味着多层架构。但是,您似乎没有以多层方式使用它。

选项1

基于this comment我已更新选项1以演示使用查询。

//Your dataset first needs to be linked to an appropriate underlying structure
//E.g. a Table, or a Query that selects from a single table.
//This example uses a query, and assumes FCurrentLocation is the "pertinent" one.
DataSet1.CommandText := 'SELECT * FROM TLOG WHERE LOKACIJA_ID = :a1';
DataSet1.ParamByName('a1').Value := FCurrentLocation;
DataSet1.Open;

//... Later / another method
DataSet1.Insert;
DataSet1.FieldByName('LOKACIJA_ID').AsString := FCurrentLocation;
DataSet1['OPOMBA'] := y; //Alternative to FieldByName
DataSet1.Post;

Opion 2

在存储过程中实施INSERTSELECT,然后:

StoredProc.ProcName := 'MyProc';
StoredProc.Params.ParamByName('a1').Value := x;
...
StoredProc.Open;

选项3

根据您的连接提供程序,您甚至可以将两个查询简单地放在一个语句中。

DataSet.CommandText := 'INSERT INTO TLOG (LOKACIJA_ID, OPOMBA) VALUES (:a1, :a2); ' +;
                       'SELECT * FROM TLOG WHERE LOKACIJA_ID = :a1';

选项4

某些RDBMS提供了将插入/更新的行作为同一SQL状态的一部分返回的语法。不幸的是我不确定SQL Lite。