我试图从一个在存储函数中打开的游标变量中获取数据,但是我总是得到“从序列中取出”错误消息。
以下是存储的函数:
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代码:
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代码中解决。
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;发布于 2016-05-22 15:09:18
我想我已经找到了问题和解决办法。当在PL/SQL块中打开游标时,游标索引从0开始,而Pro*C索引从1开始。问题是Pro*C根本不更新游标索引,所以有一种解决方案可以像这里那样手动进行增量。
...
while (sqlca.sqlcode == '\0')
{
sql_cursor_pl.curocn++;
EXEC SQL FETCH :sql_cursor_pl INTO :string_field;
...
}
...发布于 2016-05-13 07:51:12
问题是在执行FETCH命令之前测试的while状态。
我通常使用EXEC SQL WHENEVER NOT FOUND指令解析这些循环。下面是一个关于如何做到这一点的例子:
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中需要中断,但在代码的其余部分可能不是最佳选择)。
https://stackoverflow.com/questions/37190652
复制相似问题