繁体   English   中英

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

[英]Database error - cursor not returned from query

遇到“查询未返回游标”的问题,找到了一种解决方案,基本上可以再次重新打开查询:

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;

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

编辑:具有运行此查询的dataset1的表单使用另一种表单(form3),即它是Form3.DSProviderConnection1连接到服务器。在ServerMethodsUnit1的服务器端,我有一个DatasetProvider8,它链接到SQLQuery7(在查询的SQL中)有:从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)显示表本身会更好,所以我可以运行插入查询并仅调用表刷新?

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

选项1

基于此评论,我更新了选项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。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM