平台:vc++6.0
数据库:oracle10.1
语言:C
系统配置文件pcscfg.cfg配置如下:
char_map=string
DYNAMIC=ANSI
mode=ANSI
parse=full
SQLCHECK=SEMANTICS
RELEASE_CURSOR=NO
HOLD_CURSOR=YES
VARCHAR=YES
userid=scott/scottpwd
include=C:\Program Files\Microsoft Visual Studio\VC98\Include
include=C:\oracle\product\10.1.0\db_1\precomp\public
include=C:\oracle\product\10.1.0\db_1\OCI\include
我在PC程序中使用ANSI动态SQL方法四时出现以上错误
ANSI动态SQL方法四代码如下:/*定义绑定变量值和数据值的最大长度*/
#define MAX_VAR_LEN 200
/*定义选择列表项名称的最大长度*/
#define MAX_NAME_LEN 31/*定义宿主变量用以存储动态SQL语句*/
EXEC SQL BEGIN DECLARE SECTION;
char sql_stat[100];
EXEC SQL END DECLARE SECTION; void dysql(void); //动态SQL
void process_input(void);
void process_output(void);int main(void)
{
dysql();
return 0;
}
void dysql(void)
{
EXEC SQL ALLOCATE DESCRIPTOR 'input_desc'; //分配输入描述区
EXEC SQL ALLOCATE DESCRIPTOR 'output_desc'; //分配输出描述区
printf("\n");
/*循环处理动态SQL语句*/
for(;;)
{
printf("输入动态SQL语句(exit:退出):\n");
gets(sql_stat);
fflush(stdin);
/*exit(EXIT):退出*/
if((strncmp(sql_stat,"exit",4)==0) || (strncmp(sql_stat,"EXIT",4)==0))
break;
/*准备sql语句*/
EXEC SQL PREPARE S FROM :sql_stat;
/*定义游标*/
EXEC SQL DECLARE C CURSOR FOR S;
/*处理绑定变量*/
process_input();
/*
打开游标
select 语句:处理查询给果
其他sql语句:执行
*/
EXEC SQL OPEN C USING DESCRIPTOR 'input_desc';
if((strncmp(sql_stat,"select",6)==0) || (strncmp(sql_stat,"SELECT",6)==0))
process_output();
EXEC SQL CLOSE C;
}
EXEC SQL DEALLOCATE DESCRIPTOR 'input_desc'; //释放输入描述区
EXEC SQL DEALLOCATE DESCRIPTOR 'output_desc'; //释放输出描述区
EXEC SQL COMMIT;
printf("\n谢谢你使用动态SQL语句!.\n");
printf("\n");
/*
出错原因为:SQL-02145: 动态描述符无效
*/
} //end function dysql() void process_input(void)
{
/*定义宿主变量*/
EXEC SQL BEGIN DECLARE SECTION;
int i;
char chname[31];
int input_count;
int input_len;
int occurs;
int ANSI_varchar_type;
char input_buf[MAX_VAR_LEN];
EXEC SQL END DECLARE SECTION;
/*绑定变量-->输入描述区*/
EXEC SQL DESCRIBE INPUT S
USING DESCRIPTOR 'input_desc';
/*取得绑定变量的个数*/
EXEC SQL GET DESCRIPTOR 'input_desc' :input_count = COUNT;
/*数值类型-->变长字符串*/
ANSI_varchar_type=12;
for(i=0;i<input_count;i++)
{
occurs=i+1;
/*绑定变量名-->宿主变量*/
EXEC SQL GET DESCRIPTOR 'input_desc' VALUE :occurs:chname=NAME;
/*显示绑定变量名*/
printf("\n输入%s的值: ",chname);
/*为输入宿主变量输入数据*/
gets(input_buf);
fflush(stdin);
/*设置变量-->null终止*/
input_len=strlen(input_buf);
input_buf[input_len]='\0';
/*设置绑定变量值*/
EXEC SQL SET DESCRIPTOR 'input_desc' VALUE :occurs TYPE= :ANSI_varchar_type,LENGTH= :input_len,DATA = :input_buf;
}
}
void process_output(void)
{
/*定义宿主变量*/
EXEC SQL BEGIN DECLARE SECTION;
int i;
int output_count;
int occurs;
int type;
int len;
short indi;
char data[MAX_VAR_LEN];
char chname[MAX_NAME_LEN];
size_t chlen;
EXEC SQL END DECLARE SECTION;
/*选择列表项-->输出描述区*/
EXEC SQL DESCRIBE OUTPUT S USING DESCRIPTOR 'output_desc';
EXEC SQL GET DESCRIPTOR 'output_desc' :output_count= COUNT;
printf("\n");
chlen=0;
/*设置类型为变长字符串*/
type=12;
len=MAX_VAR_LEN;
for(i=0;i<output_count;i++)
{
occurs=i+1;
/*设置数据类型的长度*/
EXEC SQL SET DESCRIPTOR 'output_desc' VALUE :occurs TYPE=:type,LENGTH=:len;
/*取得选择列表项的名称*/
EXEC SQL GET DESCRIPTOR 'output=desc' VALUE :occurs:chname=NAME;
chlen=strlen(chname);
chname[chlen]='\0';
/*显示选择列表项的名称*/
printf("\t chname=%s ",chname);
}
printf("\n\n");
/*提取数据完毕-->退出循环*/
EXEC SQL WHENEVER NOT FOUND do break;
for(;;)
{
/*行数据-->输出描述区*/
EXEC SQL FETCH C INTO DESCRIPTOR 'output_desc';
for(i=0;i<output_count;i++)
{
occurs=i+1;
/*取得选择列表项的数据*/
EXEC SQL GET DESCRIPTOR 'output_desc' VALUE :occurs:data=DATA, :indi=INDICATOR;
chlen=strlen(data);
data[chlen]='\0';
if(indi == -1)
printf("\tdata=%s "," "); /*null-->显示为空格*/
else
printf("\tdata=%s ",data); /*not null-->显示数据*/
}
printf("\n");
}
}
---------------------------------------------------------------------------------------
请高手指点指点...
数据库:oracle10.1
语言:C
系统配置文件pcscfg.cfg配置如下:
char_map=string
DYNAMIC=ANSI
mode=ANSI
parse=full
SQLCHECK=SEMANTICS
RELEASE_CURSOR=NO
HOLD_CURSOR=YES
VARCHAR=YES
userid=scott/scottpwd
include=C:\Program Files\Microsoft Visual Studio\VC98\Include
include=C:\oracle\product\10.1.0\db_1\precomp\public
include=C:\oracle\product\10.1.0\db_1\OCI\include
我在PC程序中使用ANSI动态SQL方法四时出现以上错误
ANSI动态SQL方法四代码如下:/*定义绑定变量值和数据值的最大长度*/
#define MAX_VAR_LEN 200
/*定义选择列表项名称的最大长度*/
#define MAX_NAME_LEN 31/*定义宿主变量用以存储动态SQL语句*/
EXEC SQL BEGIN DECLARE SECTION;
char sql_stat[100];
EXEC SQL END DECLARE SECTION; void dysql(void); //动态SQL
void process_input(void);
void process_output(void);int main(void)
{
dysql();
return 0;
}
void dysql(void)
{
EXEC SQL ALLOCATE DESCRIPTOR 'input_desc'; //分配输入描述区
EXEC SQL ALLOCATE DESCRIPTOR 'output_desc'; //分配输出描述区
printf("\n");
/*循环处理动态SQL语句*/
for(;;)
{
printf("输入动态SQL语句(exit:退出):\n");
gets(sql_stat);
fflush(stdin);
/*exit(EXIT):退出*/
if((strncmp(sql_stat,"exit",4)==0) || (strncmp(sql_stat,"EXIT",4)==0))
break;
/*准备sql语句*/
EXEC SQL PREPARE S FROM :sql_stat;
/*定义游标*/
EXEC SQL DECLARE C CURSOR FOR S;
/*处理绑定变量*/
process_input();
/*
打开游标
select 语句:处理查询给果
其他sql语句:执行
*/
EXEC SQL OPEN C USING DESCRIPTOR 'input_desc';
if((strncmp(sql_stat,"select",6)==0) || (strncmp(sql_stat,"SELECT",6)==0))
process_output();
EXEC SQL CLOSE C;
}
EXEC SQL DEALLOCATE DESCRIPTOR 'input_desc'; //释放输入描述区
EXEC SQL DEALLOCATE DESCRIPTOR 'output_desc'; //释放输出描述区
EXEC SQL COMMIT;
printf("\n谢谢你使用动态SQL语句!.\n");
printf("\n");
/*
出错原因为:SQL-02145: 动态描述符无效
*/
} //end function dysql() void process_input(void)
{
/*定义宿主变量*/
EXEC SQL BEGIN DECLARE SECTION;
int i;
char chname[31];
int input_count;
int input_len;
int occurs;
int ANSI_varchar_type;
char input_buf[MAX_VAR_LEN];
EXEC SQL END DECLARE SECTION;
/*绑定变量-->输入描述区*/
EXEC SQL DESCRIBE INPUT S
USING DESCRIPTOR 'input_desc';
/*取得绑定变量的个数*/
EXEC SQL GET DESCRIPTOR 'input_desc' :input_count = COUNT;
/*数值类型-->变长字符串*/
ANSI_varchar_type=12;
for(i=0;i<input_count;i++)
{
occurs=i+1;
/*绑定变量名-->宿主变量*/
EXEC SQL GET DESCRIPTOR 'input_desc' VALUE :occurs:chname=NAME;
/*显示绑定变量名*/
printf("\n输入%s的值: ",chname);
/*为输入宿主变量输入数据*/
gets(input_buf);
fflush(stdin);
/*设置变量-->null终止*/
input_len=strlen(input_buf);
input_buf[input_len]='\0';
/*设置绑定变量值*/
EXEC SQL SET DESCRIPTOR 'input_desc' VALUE :occurs TYPE= :ANSI_varchar_type,LENGTH= :input_len,DATA = :input_buf;
}
}
void process_output(void)
{
/*定义宿主变量*/
EXEC SQL BEGIN DECLARE SECTION;
int i;
int output_count;
int occurs;
int type;
int len;
short indi;
char data[MAX_VAR_LEN];
char chname[MAX_NAME_LEN];
size_t chlen;
EXEC SQL END DECLARE SECTION;
/*选择列表项-->输出描述区*/
EXEC SQL DESCRIBE OUTPUT S USING DESCRIPTOR 'output_desc';
EXEC SQL GET DESCRIPTOR 'output_desc' :output_count= COUNT;
printf("\n");
chlen=0;
/*设置类型为变长字符串*/
type=12;
len=MAX_VAR_LEN;
for(i=0;i<output_count;i++)
{
occurs=i+1;
/*设置数据类型的长度*/
EXEC SQL SET DESCRIPTOR 'output_desc' VALUE :occurs TYPE=:type,LENGTH=:len;
/*取得选择列表项的名称*/
EXEC SQL GET DESCRIPTOR 'output=desc' VALUE :occurs:chname=NAME;
chlen=strlen(chname);
chname[chlen]='\0';
/*显示选择列表项的名称*/
printf("\t chname=%s ",chname);
}
printf("\n\n");
/*提取数据完毕-->退出循环*/
EXEC SQL WHENEVER NOT FOUND do break;
for(;;)
{
/*行数据-->输出描述区*/
EXEC SQL FETCH C INTO DESCRIPTOR 'output_desc';
for(i=0;i<output_count;i++)
{
occurs=i+1;
/*取得选择列表项的数据*/
EXEC SQL GET DESCRIPTOR 'output_desc' VALUE :occurs:data=DATA, :indi=INDICATOR;
chlen=strlen(data);
data[chlen]='\0';
if(indi == -1)
printf("\tdata=%s "," "); /*null-->显示为空格*/
else
printf("\tdata=%s ",data); /*not null-->显示数据*/
}
printf("\n");
}
}
---------------------------------------------------------------------------------------
请高手指点指点...
SQL-02145: Invalid dynamic descriptor
Cause: An attempt to access an unallocated or invalid descriptor was encountered.
Action: For ANSI descriptors, check that descriptor name is valid and descriptor has been allocated and not previously deallocated. Or if using Oracle descriptors (sqlda) with mode=ansi also use dynamic=oracle.我自己乱翻译下:
SQL-02145: 无效的动态描述符
原因: 试图访问一个未分配的或无效的描述符
动作: 对于ANSI的描述符, 检查这个描述符的名字是不是有效, 并且描述符是不是被分配并且没有在事先解除分配. 或者在ansi模式下使用Oracle的描述符(sqlda) 并且使用dynamic=oracle.楼主尝试使用下动作里的解决办法?
动态描述符主要指哪一些???一下是分配描述符吗?
EXEC SQL ALLOCATE DESCRIPTOR 'input_desc'; //分配输入描述区
EXEC SQL ALLOCATE DESCRIPTOR 'output_desc'; //分配输出描述区 一下是解除分配吗?
EXEC SQL DEALLOCATE DESCRIPTOR 'input_desc'; //释放输入描述区
EXEC SQL DEALLOCATE DESCRIPTOR 'output_desc'; //释放输出描述区
程序中没有用Oracle的描述符(sqlda),并且dynamic=ansi. 怎么回事???
再指点指点......
应该是指oracle关键字吧你使用了一个没有分配的关键字?
如果不是, 那么"在ansi模式下使用Oracle的描述符(sqlda) 并且使用dynamic=oracle"应该可以解决问题."在ansi模式下使用Oracle的描述符(sqlda)"
这个怎么使用, 我也不知道, 呵呵
DYNAMIC=ANSI
mode=ANSI
parse=full
把第二行改为DYNAMIC=oracle
并且执行"在ansi模式下使用Oracle的描述符(sqlda)" 动作里写的话不是出错的原因, 而是出错的解决办法
在第 320 行, 第 11 列, 文件 .\democ.pc 有语义错误:
EXEC SQL ALLOCATE DESCRIPTOR 'output_desc_arer'; //分配输出描述区
..........1哈哈
我已解决了。
原因是:我把“分配输入/输出描述区 ”的名字给改成了'output_desc_arer'/'input_desc_arer',
也许是名字冲突吧。
不过非常感谢你的认真和帮助,
以后还得多多请教。
现在有问题如下:
error C2043: illegal break
if (sqlca.sqlcode == 100) break ;
------------------------------------------------------------
程序代码如下(耐心点):
出错语句. /* EXEC SQL SELECT COUNT(LoginID) into :ok from Teacher where LoginID=:logpwd; */ {
struct sqlexd sqlstm;
sqlstm.sqlvsn = 12;
sqlstm.arrsiz = 4;
sqlstm.sqladtp = &sqladt;
sqlstm.sqltdsp = &sqltds;
sqlstm.stmt = "select count(LoginID) into :b0 from Teacher where LoginID\
=:b1";
sqlstm.iters = (unsigned int )1;
sqlstm.offset = (unsigned int )562;
sqlstm.selerr = (unsigned short)1;
sqlstm.cud = sqlcud0;
sqlstm.sqlest = (unsigned char *)&sqlca;
sqlstm.sqlety = (unsigned short)256;
sqlstm.occurs = (unsigned int )0;
sqlstm.sqhstv[0] = ( void *)&ok;
sqlstm.sqhstl[0] = (unsigned int )sizeof(int);
sqlstm.sqhsts[0] = ( int )0;
sqlstm.sqindv[0] = ( void *)0;
sqlstm.sqinds[0] = ( int )0;
sqlstm.sqharm[0] = (unsigned int )0;
sqlstm.sqadto[0] = (unsigned short )0;
sqlstm.sqtdso[0] = (unsigned short )0;
sqlstm.sqhstv[1] = ( void *)logpwd;
sqlstm.sqhstl[1] = (unsigned int )9;
sqlstm.sqhsts[1] = ( int )0;
sqlstm.sqindv[1] = ( void *)0;
sqlstm.sqinds[1] = ( int )0;
sqlstm.sqharm[1] = (unsigned int )0;
sqlstm.sqadto[1] = (unsigned short )0;
sqlstm.sqtdso[1] = (unsigned short )0;
sqlstm.sqphsv = sqlstm.sqhstv;
sqlstm.sqphsl = sqlstm.sqhstl;
sqlstm.sqphss = sqlstm.sqhsts;
sqlstm.sqpind = sqlstm.sqindv;
sqlstm.sqpins = sqlstm.sqinds;
sqlstm.sqparm = sqlstm.sqharm;
sqlstm.sqparc = sqlstm.sqharc;
sqlstm.sqpadto = sqlstm.sqadto;
sqlstm.sqptdso = sqlstm.sqtdso;
sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
if (sqlca.sqlcode == 100) break; //此为出错原因
if (sqlca.sqlcode < 0) sql_error();
}
------------------------------
正确语句: /* EXEC SQL CALL teacher_pack.islogin_proc(:logpwd,:logname,:ok); */ {
struct sqlexd sqlstm;
sqlstm.sqlvsn = 12;
sqlstm.arrsiz = 4;
sqlstm.sqladtp = &sqladt;
sqlstm.sqltdsp = &sqltds;
sqlstm.stmt = "call teacher_pack.islogin_proc(:b0,:b1,:b2)";
sqlstm.iters = (unsigned int )1;
sqlstm.offset = (unsigned int )562;
sqlstm.cud = sqlcud0;
sqlstm.sqlest = (unsigned char *)&sqlca;
sqlstm.sqlety = (unsigned short)256;
sqlstm.occurs = (unsigned int )0;
sqlstm.sqhstv[0] = ( void *)logpwd;
sqlstm.sqhstl[0] = (unsigned int )9;
sqlstm.sqhsts[0] = ( int )0;
sqlstm.sqindv[0] = ( void *)0;
sqlstm.sqinds[0] = ( int )0;
sqlstm.sqharm[0] = (unsigned int )0;
sqlstm.sqadto[0] = (unsigned short )0;
sqlstm.sqtdso[0] = (unsigned short )0;
sqlstm.sqhstv[1] = ( void *)logname;
sqlstm.sqhstl[1] = (unsigned int )9;
sqlstm.sqhsts[1] = ( int )0;
sqlstm.sqindv[1] = ( void *)0;
sqlstm.sqinds[1] = ( int )0;
sqlstm.sqharm[1] = (unsigned int )0;
sqlstm.sqadto[1] = (unsigned short )0;
sqlstm.sqtdso[1] = (unsigned short )0;
sqlstm.sqhstv[2] = ( void *)&ok;
sqlstm.sqhstl[2] = (unsigned int )sizeof(int);
sqlstm.sqhsts[2] = ( int )0;
sqlstm.sqindv[2] = ( void *)0;
sqlstm.sqinds[2] = ( int )0;
sqlstm.sqharm[2] = (unsigned int )0;
sqlstm.sqadto[2] = (unsigned short )0;
sqlstm.sqtdso[2] = (unsigned short )0;
sqlstm.sqphsv = sqlstm.sqhstv;
sqlstm.sqphsl = sqlstm.sqhstl;
sqlstm.sqphss = sqlstm.sqhsts;
sqlstm.sqpind = sqlstm.sqindv;
sqlstm.sqpins = sqlstm.sqinds;
sqlstm.sqparm = sqlstm.sqharm;
sqlstm.sqparc = sqlstm.sqharc;
sqlstm.sqpadto = sqlstm.sqadto;
sqlstm.sqptdso = sqlstm.sqtdso;
sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
if (sqlca.sqlcode < 0) sql_error();
} 两条语句在同一个函数中:
main()
{
....
switch(logflag[0])
{
case 'm':
case 'M':
managerModern(logname,logpwd); //进入管理员模块
break;
case 't':
case 'T':
teacherFunc(logname,logpwd); //进入老师模块
break;
case 's':
case 'S':
studentFunc(logname,logpwd); //进入学生模块
break;
default:
printf("\n身份有误!\n");
exit(1);
break;
}
....
}
teacherFunc(logname,logpwd); //进入老师模块
{
.....
//EXEC SQL SELECT COUNT(LoginID) into :ok from Teacher where LoginID=:logpwd; //出错语句
EXEC SQL CALL teacher_pack.islogin_proc(:logpwd,:logname,:ok); //检查此老师是否注册
.....
}