1. 举例
/*宿主变量的定义 */
EXEC SQL BEGIN DECLARE SECTION;
char username[20],password[20],servername[20];
varchar person_name[50];
varchar person_phone[25];
EXEC SQL END DECLARE SECTION;
void main(void)
{
printf(" Please input username:");
scanf("%s",username);
printf(" Please input password :");
scanf("%s",password);
printf(" Please input servername :");
scanf("%s",servername);
/*登录数据库*/
EXEC SQL LOGIN :username PASSWORD :password SERVER :servername;
/*对数据库操作 */
EXEC SQL SELECT name, phone INTO :person_name,:person_phone
FROM person.person WHERE personid = '1';
printf("\n 对应的人员姓名为: %s\n", person_name);
printf("\n 对应的联系电话为: %s\n", person_phone);
// EXEC SQL COMMIT WORK;
/*退出数据库*/
EXEC SQL LOGOUT;
}
2. 预编译命令
FILE 指定.pc 文件的完整路径
CHECK 指定是否检查不符合入门级标准的 SQL 语句,FALSE 表示不检查,TRUE 表示检查; 默认为 FALSE
TYPE 指定生成文件类型。C 代表 c 源文件,CPP 代表 c++源文件; 默认为 C
MACRO_FILE 宏头文件路径
MODE 编译模式,STD 表示标准编译模式、DM 表示达梦编译模式、ORACLE 表示兼容部分 ORACLE 语法的编译模式、DB2 表示兼容部分 DB2 语法的编译模式,默认 STD 编译模式
DEFINE 条件编译宏
HELP 打印帮助信息
3. 编译
需要头文件:dpc_dll.h DPItypes.h
链接需要库:libdmdpc.so
proc编译:dpc
# dpc FILE=test.pc CHECK=FALSE
4. 异常处理
# WHENEVER 语句
EXEC SQL WHENEVER <条件> < 异常动作>;
<条件>: SQLERROR │ NOT FOUND
<异常动作>: CONTINUE │GOTO <标号> │GO TO <标号>
例子:
EXEC SQL WHENEVER SQLERROR GOTO err_proc;
EXEC SQL WHENEVER NOT FOUND GOTO err_proc;
...
err_proc: //标准的 C 语言的标号
EXEC SQL WHENEVER NOT FOUND CONTINUE;
通过 SQLCODE 和 SQLSTATE 获取 SQL 语句执行的信息
long SQLCODE;
char SQLSTATE[6];
DM_SQL 嵌入式程序中 SQLCODE 是一个 long 型变量,可能的值有:
- SQLCODE < 0 SQL 语句执行发生异常
- SQLCODE = 0 SQL 语句执行成功
- SQLCODE > 0 SQL 语句执行中产生警告。如 100 表示找不到数据(如删除一个空表中的记录等)
DM_SQL 嵌入式程序中 SQLSTATE 是一个 char[6] 型的变量。其前两个字符表示类别代码,随后的三个字符表示子类的代码
例如: 当 SQLSTATE = “22012”时,22 是类别代码,表示 SQL 语句发生了数据异常
5. 提交与回滚
提交:
格式:COMMIT WORK;
使用说明:在应用程序中使用该语句显式地结束事务,如果没有显式地提交事务,而应用程序又非正常终止,则最后一个未提交的工作单元被回滚
回滚:
格式:ROLLBACK WORK;
功能:废除当前逻辑工作单元中的所有操作,并结束该工作单元
使用说明: 编程者应准确及时的使用这两个语句。 一般要在一个事务处理完之后及时提交或回滚,以表示一个事务结束。否则该事务可能因为其它事务(如创建基表语句CREATE )的提交而提交,从而造成数据的一致性错误,这种情况在多模块程序设计时应特别注意。另外,在执行这两个语句后, DBMS 系统可释放一些系统资源,有利于程序及DBMS 的正常工作
6. 动态SQL
1. 立即执行
格式:EXEC SQL EXECUTE IMMEDIATE < SQL 动态语句文本 >;
功能:动态地准备和执行一条语句。该语句首先分析动态语句文本,如果有错误则不执行它,并在 SQLCODE 中返回错误码
使用说明:用该方法处理的 SQL 语句一定不是 SELECT 语句,而且不包含任何虚拟的输入宿主变量
2. 分三步
a) 构造一个动态 SQL 语句
b) 用 PREPARE 语句来分析和命名该动态 SQL 语句
格式:EXEC SQL PREPARE [SQL 语句名] FROM [SQL 动态语句文本 ];
使用说明:用该方法处理的 SQL 语句,不能是 SELECT 语句。该语句可能包含虚拟输入宿主变量(用问号表示)
例子:
strcpy(sql_stmt, "DELETE FROM person.person WHERE personid = ?");
EXEC SQL PREPARE stmt FROM :sql_stmt;
c) 用 EXECUTE 语句来执行它
格式:EXEC SQL EXECUTE [SQL 语句名] [结果使用子句 ];
EXEC SQL EXECUTE stmt USING :personid;
3. SELECT语句
首先,用 PREPARE 语句来分析和命名该动态 SQL 语句
a) 动态申明游标语句
格式:EXEC SQL DECLARE [ 游标名] CURSOR FOR [语句名];
使用说明: [ 语句名]标识与游标相联系的 SQL 语句,该名字要在前面的 PREPARE语句中说明,[ 游标名]标识该动态 SQL 语句对应的游标名
b) 动态打开游标语句
格式:EXEC SQL OPEN [ 游标名] [USING : host_variable [,.]];
使用说明:[ 游标名]是要打开的游标的名字, host_variable 是实际宿主变量,用于替换动态 SQL 语句中的虚拟宿主变量
c) 动态拨动游标语句
格式:EXEC SQL FETCH [ 游标名] INTO :host_variable[,.];
使用说明:[ 游标名]是游标名, FETCH 语句从该游标所标识的缓冲区中读取一行,并将所提取的数据赋给 INTO 子句指向的一组宿主变量中
d) 动态关闭语句
格式:EXEC SQL CLOSE [ 游标名];
//举例
strcpy(SqlStr,"SELECT \"name\", \"phone\" FROM person WHERE \"personid\" = ?");
EXEC SQL PREPARE S1 FROM :SqlStr;
EXEC SQL DECLARE C1 CURSOR FOR S1;
EXEC SQL OPEN C1 USING :person_no;
printf("The result is:%s\n",person_no);
EXEC SQL FETCH C1 INTO :person_name,:person_phone;
printf("NO=%s,NAME=%s\n\n",person_phone, person_name);
EXEC SQL CLOSE C1;
4. 插入、更新、删除语句
//插入
EXEC SQL insert into t(name) values('furong');
EXEC SQL COMMIT WORK;
//更新
EXEC SQL UPDATE t SET name = 'furong' WHERE id = '1';
EXEC SQL FETCH C1 INTO :name;
EXEC SQL UPDATE t SET name = :name WHERE CURRENT OF C1;
//删除
EXEC SQL DELETE FROM t WHERE personid = '1';
EXEC SQL DELETE FROM t WHERE CURRENT OF C1;