在多个搜索条件下使用光标 [英] Using cursor for multiple search conditions

查看:89
本文介绍了在多个搜索条件下使用光标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我想为我的英语不好而道歉,并且有可能我错过了一些重要信息给你们。

To begin with I want to apologise for my bad english and it's possible that I miss some crucial information for you guys.

反正。我正在开发带有子文件的显示文件,以显示一些记录。当显示一个选择时,它就像一种魅力,但现在我想为用户开发一种搜索功能。因此,当用户输入不同的搜索条件时,选择将改变,并且光标必须以新的选择以某种方式更新。我正在扯掉头发,我真的无法使它正常工作。

Anyways. I am developing a display file with a subfile to show some records. It works like a charm when showing one select but now i want to develop a search-function for the users. So when the user enters different search-conditions the select will change and the cursor must somehow update with the new select. I am ripping my hair off, I really can't get this to work.

我在 mcpressonine论坛上找到了一个帖子,有个男人和我完全一样的问题,他确实以某种方式解决了这个问题,但是我真的不理解他的所作所为-除了将声明游标放在我也做过的子过程中-没有成功。

I found a post from "mcpressonine"-forum, there is a guy who got the exact same problem as me and he did somehow solve this but I dont really understand what he did - except from putting the declare cursor in a subprocedure which I also did - without success. 

这里是他的论坛帖子的链接:
他的帖子

Here is a link to his forum post: His post

如果有人解释他做了什么。也许这家伙的解决方案不再有效,因为他的职位已经10岁了。
告诉我信息是否足够,我将一路纠正。

I would be very thankful if someone explains what he did. Maybe this guys solutions are no longer valid since his post is 10 years old now. Tell me if the information is not enough and I will correct along the way.

谢谢!
此致Jesper

Thanks! Kind regards, Jesper

推荐答案

要记住的是 DECLARE 语句不可执行。这是一个编译时声明。 PREPARE OPEN 是可执行的。

The thing to keep in mind is that the DECLARE statement is not executable. It is a compile time declaration. PREPARE and OPEN are executable.

下面是一个完全使用动态SQL的程序,请注意,实际上从未调用 DeclareCursor 子例程。重要的是执行 PREPARE 语句时在gSqlStmt中的语句。

Below is a fully working program that uses dynamic SQL, note that the DeclareCursor subroutine is never actually called. What matters is the statement, in gSqlStmt, at the time the PREPARE statement is executed.

**FREE
ctl-opt main(mymain);
ctl-opt option(*srcstmt);

dcl-c QUOTE const('''');

dcl-s gSqlStmt varchar(500);

dcl-proc MyMain;
  dcl-s company char(3);
  dcl-s part    char(25);
  dcl-s desc    char(30);
  dcl-s msg     char(50);
  dcl-s selComp char(3);

  selComp = 'A06';
  gSqlStmt = 'select pmco#, pmpart, pmdesc'
           + ' from pdpmast'
           + ' where pmco# = ' + QUOTE + selComp + QUOTE;

  exsr OpenCursor;
  exsr FetchData;
  exec SQL close C1;

  selComp = 'A15';
  gSqlStmt = 'select pmco#, pmpart, pmdesc'
           + ' from pdpmast'
           + ' where pmco# = ' + QUOTE + selComp + QUOTE;
  exsr OpenCursor;
  exsr FetchData;
  exec SQL close C1;

  *INLR = *ON;
  return;

  begsr DeclareCursor;
     exec SQL
       declare C1 cursor for S1;
  endsr;

  begsr OpenCursor;
    exec SQL prepare S1 from :gSqlStmt;
    exec SQL open C1;
  endsr;

  begsr FetchData;
    exec sql fetch next from C1 into :company, :part, :desc;
    msg = company + ':' + part + ':' + %subst(desc:1:20);
    dsply msg;
  endsr;
end-proc;

除了没有错误处理外,上面的方法还包含直接连接输入变量selComp的错误做法,变成声明。由于SQL注入攻击,在任何语言中都不是一个好主意。

Besides not having any error handling, the above contains the bad practice of directly concatenating an input variable, selComp, into a statement. This is not a good idea in any language due to SQL Injection attacks.

下面是使用参数标记的更好版本。请注意,该语句不再需要更改。所以我只需要准备一次。记录的选择取决于 OPEN ... USING ... 语句被调用时selComp的值。

A better version that uses parameter markers is below. Note that the statement doesn't need to change any longer. So I only need to prepare it once. The record selection depends on the value of selComp at the time the OPEN ... USING... statement is called.

**FREE
ctl-opt main(mymain);
ctl-opt option(*srcstmt);

dcl-s gSqlStmt varchar(500);

dcl-proc MyMain;
  dcl-s company char(3);
  dcl-s part    char(25);
  dcl-s desc    char(30);
  dcl-s msg     char(50);
  dcl-s selComp char(3);

  gSqlStmt = 'select pmco#, pmpart, pmdesc'
           + ' from pdpmast'
           + ' where pmco# = ?';
  exec SQL prepare S1 from :gSqlStmt;

  selComp = 'A06';
  exsr OpenCursor;
  exsr FetchData;
  exec SQL close C1;

  selComp = 'A15';
  exsr OpenCursor;
  exsr FetchData;
  exec SQL close C1;

  *INLR = *ON;
  return;

  begsr DeclareCursor;
     exec SQL
       declare C1 cursor for S1;
  endsr;

  begsr OpenCursor;
    exec SQL open C1 using :selComp;
  endsr;

  begsr FetchData;
    exec sql fetch next from C1 into :company, :part, :desc;
    msg = company + ':' + part + ':' + desc;
    dsply msg;
  endsr;
end-proc;

但是,这里实际上并不需要动态SQL。带有宿主变量的静态语句可以正常工作。使用静态SQL,我不需要任何 PREPARE ,也不需要在 OPEN 上指定selComp。所有这些都是在编译时自动完成的。

However, dynamic SQL isn't actually needed here. A static statement with a host variable will work just fine. With static SQL, I don't need to PREPARE anything, nor specify selComp on the OPEN. All that is done automatically at compile time.

**FREE
ctl-opt main(mymain);
ctl-opt option(*srcstmt);

dcl-s gSqlStmt varchar(500);

dcl-proc MyMain;
  dcl-s company char(3);
  dcl-s part    char(25);
  dcl-s desc    char(30);
  dcl-s msg     char(50);
  dcl-s selComp char(3);

  selComp = 'A06';
  exsr OpenCursor;
  exsr FetchData;
  exec SQL close C1;

  selComp = 'A15';
  exsr OpenCursor;
  exsr FetchData;
  exec SQL close C1;

  *INLR = *ON;
  return;

  begsr DeclareCursor;
     exec SQL
       declare C1 cursor for
          select pmco#, pmpart, pmdesc
           from pdpmast
           where pmco# = :selComp;
  endsr;

  begsr OpenCursor;
    exec SQL open C1;
  endsr;

  begsr FetchData;
    exec sql fetch next from C1 into :company, :part, :desc;
    msg = company + ':' + part + ':' + desc;
    dsply msg;
  endsr;
end-proc;

这篇关于在多个搜索条件下使用光标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆