用户能够将任何一个宿主变量同一个指示变量进行关联。指示器变量必须被定义为 2 个字
节的整数类型( short),在 SQL 语句中,如果没有指定 INDICATOR 关键字,指示变量必须
紧跟在与其关联的宿主变量后。如果使用 DECLARE SECTION 声明宿主变量,则相关指示
变量也必须采用 DECLARE SECTION 进行声明。
- 短整型变量,用于处理数据库的NULL值,监督和管理与其相关联的宿主变量。
- 主要用在输出, 即当宿主变量用于接收数据库的返回数据时.
- 引用语法:
:host_variable INDICATOR :indicator_variable
或者
:host_variable:indicator_variable
通过在宿主变量后用指示变量, 检测是否返回了NULL.
- 常用结构模块
EXEC SQL BEGIN DECLARE SECTION;
char desc[35];
short ind_desc;
EXEC SQL END DECLARE SECTION;
…
EXEC SQL SELECT emp_desc INTO :desc :ind_desc FROM emp WHERE emp_no=7788;
If(ind_desc < 0)
cout<<“emp_desc is NULL”;
else
cout<< desc << endl;
varchar类型在经过proc预编译后会变成
typedef struct { unsigned short len; unsigned char arr[1]; } varchar;
可以看出,字符串部分存储在arr指向的内存空间,所以对varchar类型的变量进行字符串访问的时候需要提取arr成员,综合实例如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "sqlca.h"
//演示 指示变量,用来主的对宿主变量做说明
extern sqlgls(char * , size_t *, size_t * );
extern sqlglmt(void *,char *,size_t *,size_t *);
void sqlerr02()
{
char stm[120];
size_t sqlfc, stmlen=120;
unsigned int ret = 0;
//出错时,可以把错误SQL语言给打印出来
EXEC SQL WHENEVER SQLERROR CONTINUE;
ret = sqlgls(stm, &stmlen, &sqlfc);
printf("出错的SQL:%.*s\n", stmlen, stm);
printf("出错原因:%.*s\n", sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc);
//printf("出错原因:%.70s\n", sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc);
EXEC SQL ROLLBACK WORK RELEASE;
exit(1);
}
void nodata()
{
int ret = 0;
printf("没有发现数据\n");
if (sqlca.sqlcode != 0)
{
ret = sqlca.sqlcode;
printf("sqlca.sqlcode: err:%d \n", sqlca.sqlcode);
return ;
}
}
EXEC SQL BEGIN DECLARE SECTION;
char *usrname = "scott";
char *passwd = "lzj123529";
char *serverid = "orcl";
int deptno;
varchar dname[20]; //varchar类型 和 char 类型的区别. 与编译选项有关系
short dname_ind;
varchar loc[20];
short loc_ind;
EXEC SQL END DECLARE SECTION;
void connet()
{
int ret = 0;
//连接数据库
EXEC SQL CONNECT:usrname IDENTIFIED BY:passwd USING:serverid ;
if (sqlca.sqlcode != 0)
{
ret = sqlca.sqlcode;
printf("sqlca.sqlcode: err:%d \n", sqlca.sqlcode);
return ;
}
else
{
printf("connect ok...\n");
}
}
//修改单挑数据
int main()
{
int ret = 0;
int i = 0;
EXEC SQL WHENEVER SQLERROR DO sqlerr02();
connet();
EXEC SQL WHENEVER NOT FOUND DO nodata();
printf("\nplease enter deptno: ");
scanf("%d", &deptno);
EXEC SQL select deptno, dname, loc into :deptno, :dname:dname_ind, :loc:loc_ind from dept where deptno=:deptno;
if (sqlca.sqlcode != 0)
{
ret = sqlca.sqlcode;
printf("sqlca.sqlcode: err:%d \n", sqlca.sqlcode);
return ;
}
if (dname_ind == -1)
{
printf("dname为空\n");
}
if (loc_ind == -1)
{
printf("loc为空\n");
}
printf("any key con....\n");
getchar();
printf("deptno:%d, dname:%s, loc:%s\n", deptno, dname.arr, loc.arr);
loc_ind = -1;
EXEC SQL update dept set loc=:loc:loc_ind where deptno=:deptno;//将之前获取的条目的loc更新为NULL
if (sqlca.sqlcode != 0)
{
ret = sqlca.sqlcode;
printf("sqlca.sqlcode: err:%d \n", sqlca.sqlcode);
return ;
}
EXEC SQL COMMIT WORK RELEASE;
printf("return ok...\n");
return ret ;
}
效果如下
oracle@lzj:~$ ./array
connect ok...
please enter deptno: 30
any key con....
deptno:30, dname:SALES, loc:CHICAGO
return ok...