首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Pro*C,如何在不设置“sqlcheck=semantics”选项的情况下从PL存储函数中打开的游标中提取?

使用Pro*C,如何在不设置“sqlcheck=semantics”选项的情况下从PL存储函数中打开的游标中提取?
EN

Stack Overflow用户
提问于 2016-05-12 14:57:49
回答 2查看 1.5K关注 0票数 1

我试图从一个在存储函数中打开的游标变量中获取数据,但是我总是得到“从序列中取出”错误消息。

以下是存储的函数:

代码语言:javascript
复制
CREATE OR REPLACE FUNCTION test_function RETURN SYS_REFCURSOR AS
  p_recordset SYS_REFCURSOR;
BEGIN
  OPEN p_recordset FOR SELECT '1' FROM DUAL UNION SELECT '2' FROM DUAL;
  RETURN p_recordset;
END TEST_FUNCTION;

而Pro*C代码:

代码语言:javascript
复制
int myfunction()
{
  ...
  EXEC SQL BEGIN DECLARE SECTION;
  SQL_CURSOR sql_cursor_pl;
  VARCHAR string_field[20];
  EXEC SQL END DECLARE SECTION;

  EXEC SQL ALLOCATE :sql_cursor_pl;

  // It is not possible to use embedded PL/SQL block as seen in other 
  // examples because it requieres a compilation time access to database 
  // that I don't have, so as far as I know I have to use EXEC SQL CALL
  EXEC SQL CALL sch.test_function() INTO :sql_cursor_pl;

  EXEC SQL WHENEVER NOT FOUND DO break;

  //for ( ; ; )
  while (sqlca.sqlcode == '\0')
  {
    EXEC SQL FETCH :sql_cursor_pl INTO :string_field;
    ...
  }

  EXEC SQL CLOSE :sql_cursor_pl;
  ...
}

如果我像下面这样在其他PL块中使用它,则存储函数可以正常工作,所以我认为问题应该在Pro*C代码中解决。

代码语言:javascript
复制
DECLARE
  mycursor sys_refcursor;
  string_field VARCHAR(20)
BEGIN
  mycursor := sch.test_function();
  LOOP
    FETCH mycursor INTO string_field;
    EXIT WHEN mycursor%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(string_field);
  END LOOP;
  CLOSE mycursor;
END;
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-05-22 15:09:18

我想我已经找到了问题和解决办法。当在PL/SQL块中打开游标时,游标索引从0开始,而Pro*C索引从1开始。问题是Pro*C根本不更新游标索引,所以有一种解决方案可以像这里那样手动进行增量。

代码语言:javascript
复制
...
while (sqlca.sqlcode == '\0')
{
  sql_cursor_pl.curocn++;
  EXEC SQL FETCH :sql_cursor_pl INTO :string_field;
  ...
}
...
票数 2
EN

Stack Overflow用户

发布于 2016-05-13 07:51:12

问题是在执行FETCH命令之前测试的while状态。

我通常使用EXEC SQL WHENEVER NOT FOUND指令解析这些循环。下面是一个关于如何做到这一点的例子:

代码语言:javascript
复制
while(1)
{
    EXEC SQL WHENEVER NOT FOUND DO break; // Where a no data found occurs execute a C "break" instruction.
    EXEC SQL FETCH :sql_cursor_pl INTO :string_field;
    EXEC SQL WHENEVER NOT FOUND DO ???; // Restore desired behaviour.

    ...
}

第一个指令指示Pro*C/C++在没有数据发现错误时执行break,这意味着退出while循环。需要第二个指令来恢复所需的行为(在while中需要中断,但在代码的其余部分可能不是最佳选择)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37190652

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档