编程实例

对esql*C有了一定的了解之后,下面让我们用嵌入式SQL语言写一个简单的例子。该例子的作用是根据用户输入的empnum从数据库中查找指定员工信息元组,如果没有找到则给出提示;如果找到符合查询条件的元组,则打印指定的员工信息。

编辑源文件

例 1-1

打开一个文本编辑器,编辑eg1-1.pc文件,下面为该文件内容。

/******************************************************************************
这是一个简单的esql*C程序。
根据用户输入的信息,从表中查找指定员工的信息。
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>

void error()
{
	/*对错误情况不予处理,以防止死循环*/
	EXEC SQL WHENEVER SQLERROR CONTINUE;
	/*输出错误信息*/
	sqlprint();
	EXEC SQL ROLLBACK WORK;
	exit(1);
}
int main()
{
	/* 声明宿主变量*/
	EXEC SQL BEGIN DECLARE SECTION;
	char hnum[4]; /* 用于存放用户输入的empnum信息*/
	char hname[21]; /*以下4个变量用于存放查到的员工信息*/
	char hcity[16];
	int hgrade;
	EXEC SQL END DECLARE SECTION;
	long SQLCODE; /* 用于取得系统执行语句返回的错误码 */
	char SQLSTATE[6]; /* 用于取得系统执行语句返回的错误状态,
						比错误码更详细、精确 */
	int num = 0;
	/*对错误情况进行处理*/
	EXEC SQL WHENEVER SQLERROR do error();
	/*如果没有找到,则打印信息,退出*/
	EXEC SQL WHENEVER NOT FOUND GOTO not_found;
	/* 连接神通数据库,其中"@localhost"可省略 */
	EXEC SQL CONNECT TO osrdb@localhost USER
	sysdba USING szoscar55;
	
	EXEC SQL WHENEVER SQLERROR CONTINUE;
	/*创建表之前删除表employee*/
	EXEC SQL DROP TABLE employee;
	EXEC SQL WHENEVER SQLERROR do error();
	/* 创建表employee */
    EXEC SQL CREATE TABLE employee(
        empnum CHARACTER(3) PRIMARY KEY,
        empname CHAR(20),
        grade DECIMAL(4,0),
        city VARCHAR(15));
    if (SQLCODE == 0)
        printf("表employee成功创建!\n");
		
	/*向表employee插入一条数据*/	
	EXEC SQL INSERT INTO employee VALUES('e1','艾黎',10,'北京');

	strcpy(hnum,"e1");

	/*查找满足条件的记录*/
	EXEC SQL SELECT empname, city, grade
	--得到雇员的名字、城市、级别
	INTO :hname, :hcity, :hgrade \
	FROM employee \
	WHERE empnum = :hnum; \
	/* 查找语句执行发生错误,关于SQLCODE和SQLSTATE,
	参见 应用开发 嵌入式SQL语言参考 错误处理 */
	if (SQLCODE < 0)
	{
		printf("错误: SQLCODE = %d, SQLSTATE = %s\n", \
			   SQLCODE, SQLSTATE);
		exit(1);
	}
	/* 如果找到,输出员工信息,因为是按照primary key查找的,
	所以最多只有一条结果 */
	printf("empnum = %s,empname = %s,grade = %d, city = %s ", \
		   hnum, hname, hgrade, hcity);
	/* 提交所做的工作;如果不希望所做的操作写入数据库,
	用ROLLBACK回滚所做的工作 */
	EXEC SQL DROP TABLE employee;
	EXEC SQL COMMIT WORK;
	EXEC SQL DISCONNECT;
	exit(0);
	/*没有找到用户要求的雇员信息,给出提示信息,结束程序*/
not_found:
	printf("empnum '%s' 不存在!",hnum);
	EXEC SQL DROP TABLE employee;
	EXEC SQL ROLLBACK WORK;
	EXEC SQL DISCONNECT;
	exit(1);
}

预编译

在WINDOWS环境下,运行以下预编译命令:

esqlpc -I%SZ_OSCAR_HOME%\esqlpc\include eg1-1.pc

在LINUX环境下,运行以下预编译命令:

esqlpc -I$SZ_OSCAR_HOME/esqlpc/include eg1-1.pc

得到输出文件eg1-1.c。

注解

运行预编译程序esqlpc前必须确定已经安装了神通数据库套件的ESQL系统组件。并且在命令行窗口下进入eg1-1.pc所在的目录。这两个条件对于以下的步骤也都需要。

编译和链接

在WINDOWS环境下,用VC集成开发环境下的C编译器时,在命令行窗口中运行如下编译命令:

cl /c /I%SZ_OSCAR_HOME%\esqlpc\include -I%SZ_OSCAR_HOME%\onet /D
"WIN32" eg1-1.c

得到eg1-1.obj目标文件。

然后运行如下链接命令:

link onet.lib esql.lib /libpath:"%SZ_OSCAR_HOME%\esqlpc\win32"
/libpath:"%SZ_OSCAR_HOME%\onet\win32\dll" eg1-1.obj

在和eg1-1.obj同一个目录下生成eg1-1.exe可执行文件。

在LINUX环境下,用gcc编译器时,在命令行窗口运行如下编译命令:

gcc -DLINUX eg1-1.c -I$SZ_OSCAR_HOME/esqlpc/include
-I$SZ_OSCAR_HOME/onet -L$SZ_OSCAR_HOME/bin -lesql -lonet -lpthread
-o eg1-1.exe

在和eg1-1.c同一个目录下生成eg1-1.exe可执行文件。

运行

运行前,确保数据库服务器在本机上,否则需要把源文件中的localhost改为数据库服务器所在的机器的IP地址或者机器的名字。

用交互式SQL登录数据库服务器,检查用户oscar是否存在,密码是否为zjuhxy,如果不正确,请修改。详细的检查请参见本章1.6小节,"范例约定"。

经过前面的一系列准备工作,现在可以运行测试用例。运行方法和其它可执行文件一样,一般可以在命令行窗口输入eg1-1命令,或者直接双击eg1-1.exe可执行文件,运行该测试例子。

运行后,屏幕上显示如下提示语句:

请输入需要查找的员工号 (像 'E1'):

根据提示,输入E0~E5之间的序号,屏幕上就会输出相应员工的信息;否则,会打印不存在该员工信息的提示信息。

整个运行过程如下所示:

E:\egs>eg1-1.exe
请输入需要查找的员工号 (像 'E1'):E1
empnum = E1,empname = 李文 ,grade = 3, city = 杭州
E:\egs>

如果输入一个不存在的雇员号码,屏幕上将会输出:

E:\egs>eg1-1.exe
请输入需要查找的员工号 (像 'E1'):E7
empnum 'E7' 不存在!
E:\egs>

其中E:egs是存放eg1-1.exe可执行文件的目录,用户可以把可执行文件存放在任何目录下。

至此,我们的第一个例子已经成功运行起来了。要进行复杂的嵌入式SQL应用程序的开发,请继续阅读后续章节。

注解

这是在WINDOWS环境下的运行示例显示,如果在LINUX下,稍有不同。不同之处在于路径分隔斜杠方向是相反的, 另外命令行提示符的显示也会有所不同。另外,在LINUX环境下,如果试图运行eg1-1.exe时出现Permission denied错误,那么可能是因为它没有可执行权限,需要用chmod +x eg1-1.exe命令给它可执行权限。