所以我无法弄清楚为什么它不断抛出这个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;
}
它符合,但输出的所有内容都是
过去获取....
ORA-01002:提取失序
我已经尝试了很多东西,但却失去了它们。
答案 0 :(得分:0)
您的提取失败,因为在此之前打开,声明和准备都失败了,但您没有检查这些错误。如果你这样做,你会收到ORA-00911: invalid character
错误,因为:
strcpy((char *)sql_statement.arr,"select supplierNumber, supplierName ");
strcat((char *)sql_statement.arr,"from supplier ");
strcat((char *)sql_statement.arr,"where supplierNumber < > 1;");
构建的语句是
select supplierNumber, supplierName from supplier where supplierNumber < > 1;
但是你这样做:
exec sql PREPARE S1 FROM :sql_statement;
与动态SQL和JDBC调用一样,此prepare只能使用单个语句。构造字符串末尾的分号是一个语句分隔符,在此上下文中没有任何意义,就解析器而言它是无效的。
所以只需删除分号:
strcpy((char *)sql_statement.arr,"select supplierNumber, supplierName ");
strcat((char *)sql_statement.arr,"from supplier ");
strcat((char *)sql_statement.arr,"where supplierNumber < > 1");
并在每个exec sql
之后添加错误检查。