ORA-01002: fetch out of sequence C++

◇◆丶佛笑我妖孽 提交于 2019-12-25 04:24:39

问题


So I can not figure out what is wrong why it keeps throwing this ORA-01002:

/**

//  compile: oracleCC fileName
//  Execute  a hardCoded sql query


/**  Program run snapshot

Connected to ORACLE as user: sp201511@cs11g

Query is  select supplierName from Supplier  where supplierNumber = 1

supplier name = Ray

*/


#include <iostream.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>

// Parse=partial by default when code=cpp so, preprocessor directives are
// recognized and parsed fully.
#define     UNAME_LEN      20
#define     PWD_LEN        40

// Declare section is required when CODE=CPP and/or PARSE={PARTIAL|NONE}
exec sql begin declare section;
  VARCHAR username[UNAME_LEN];  // VARCHAR is an ORACLE supplied struct
                                // Has actual data & length
  varchar password[PWD_LEN];    // varchar can be in lower case also
  varchar sql_statement[1000];  //holds the sql stat being constructed..
  int supplierNo;
  char    inputSupplierName[50];        //entered using cin
  varchar outputSupplierName[50];       //retrieved output from database

exec sql end declare section;

// Declare error handling function
void sql_error(char *msg);
void connectToDatabase();
void commitAndExit() ;
void buildAhardCodedSQL();
void prepareAndExecuteIt ();
exec sql include sqlca;

main()
{

//  Call sql_error() function on any error in an embedded SQL statement
    exec sql WHENEVER SQLERROR DO sql_error("Oracle error");


    exec sql
        WHENEVER SQLERROR
        DO sql_error("ORACLE error:");
    connectToDatabase();

    buildAhardCodedSQL();
    prepareAndExecuteIt ();
    commitAndExit();

}

void connectToDatabase() {

/*  Hardcoded username and password  */
    strcpy((char *)username.arr,"myusername");
    strcpy((char *)password.arr,"password.");
    username.len = strlen((char *) username.arr);
    password.len = strlen((char *) password.arr);

//  CONNECTS TO DATABASE
    exec sql CONNECT :username IDENTIFIED BY :password;

    cout << "\nConnected to ORACLE as user: "
                << (char *)username.arr << endl << endl;

}


void commitAndExit() {

    exec sql commit work release;
    exit(0);
}
void sql_error(char *msg)
{
    exec sql WHENEVER SQLERROR CONTINUE;
    cout << endl << msg << endl;
    cout << sqlca.sqlerrm.sqlerrmc << endl;
    exec sql rollback release;
    exit(1);
}

void buildAhardCodedSQL() {
    strcpy((char *)sql_statement.arr,"select supplierNumber, supplierName ");
    strcat((char *)sql_statement.arr,"from supplier ");
    strcat((char *)sql_statement.arr,"where supplierNumber < > 1;");
    // Display the SQL statement and its current input host variable.
    cout << "Query is  " << (char *) sql_statement.arr << endl;
}
void  prepareAndExecuteIt() {

//  Prepare the query; define a cursor, execute it...

    sql_statement.len = strlen((char *) sql_statement.arr);
    exec sql PREPARE S1 FROM :sql_statement;

/* The declare statement associates a cursor with a
 * PREPAREd statement.  The cursor name, like the statement
 * name, does not appear in the Declare Section.
 * A single cursor name can not be declared more than once.
*/

    exec sql declare C1 cursor FOR S1;

    exec sql open C1;

    exec sql FETCH C1 INTO :supplierNo, :outputSupplierName;

     if ( sqlca.sqlcode !=  0) {
        cout << "past fetch..." <<endl;

        cout << sqlca.sqlerrm.sqlerrmc << endl;
        exec sql rollback release;
        exit(1);
     }
     cout << "supplier name = " << (char *)outputSupplierName.arr << endl;
     cout << "supplier number = " << supplierNo << endl;
   exec sql close C1;
}

It complies and everything but the output is

past fetch....

ORA-01002: fetch out of sequence

ive tried so many things im losing it guys.


回答1:


Your fetch is failing because the open, declare and prepare all failed before that point, but you didn't check for any errors from those. If you did you'd get an ORA-00911: invalid character error, because of this:

    strcpy((char *)sql_statement.arr,"select supplierNumber, supplierName ");
    strcat((char *)sql_statement.arr,"from supplier ");
    strcat((char *)sql_statement.arr,"where supplierNumber < > 1;");

The statement that builds is

select supplierNumber, supplierName from supplier where supplierNumber < > 1;

But then you do:

exec sql PREPARE S1 FROM :sql_statement;

As with dynamic SQL and JDBC calls, this prepare can only take a single statement. The semicolon at the end of your constructed string is a statement separator which doesn't have any meaning in this context, and it is invalid as far as the parser is concerned.

So just remove that semicolon:

    strcpy((char *)sql_statement.arr,"select supplierNumber, supplierName ");
    strcat((char *)sql_statement.arr,"from supplier ");
    strcat((char *)sql_statement.arr,"where supplierNumber < > 1");

and add an error check after each exec sql.



来源:https://stackoverflow.com/questions/28756339/ora-01002-fetch-out-of-sequence-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!