Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1791391
  • 博文数量: 600
  • 博客积分: 10581
  • 博客等级: 上将
  • 技术积分: 6205
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-06 10:13
文章分类
文章存档

2016年(2)

2015年(9)

2014年(8)

2013年(5)

2012年(8)

2011年(36)

2010年(34)

2009年(451)

2008年(47)

分类: 数据库开发技术

2009-08-26 11:11:21

标准ESQL语法

ESQL/C(Embedded SQL,即嵌入式SQL)使得C程序员可以将SQL语句直接嵌入C程序。任何可交互输入的SQL语句都可用于C程序中,但有些可用于C程序中的SQL语句却不能用于交互模式。关于ESQL的规则主要有:

SQL语句加上EXEC SQL前缀,以此来区分ESQL语句和普通C语句。ESQL语句也以“;”结束。

☆ 可执行的ESQL语句可放在任何可执行C语句能够出现的地方。

ESQL语句前缀既可以大写,也可以小写,但为了使ESQL语句与普通C语句有明显区别,建议使用大写的前缀。

☆ 除了变量申明外,几乎每一个ESQL语句后都应检查SQLCODE的值。该值为0表示成功执行了ESQL语句,若小于0表示执行ESQL语句时出错,大于0通常表示一个警告信息。对于informix数据库,可以在shell里使用命令

finderr  [errno]

来获取错误信息。

6.1.1 主变量

主变量是一般的C变量,其间的区别仅在于主变量既可用于ESQL语句,也可用于普通C语句,而一般的C变量则只能用于普通C语句。主变量必须申明在下列两个语句之间:

EXEC SQL BEGIN DECLARE SECTION

EXEC SQL END DECLARE SECTION

ESQL语句中使用主变量时,必须加前缀“:”(冒号)。在普通C语句中使用主变量与一般C变量的用法相同。例如,下例定义主变量更改保证金帐户的余额:

int UpdateEacc(char *accno, double bal)

{

EXEC SQL BEGIN DECLARE SECTION;

char           ea_accno[17];

double         ea_eamt;

EXEC SQL END DECLARE SECITON;

 

strcpy (ea_accno, accno);

ea_eamt = bal;

 

EXEC SQL UPDATE ca_eacc SET ea_eamt = :ea_eamt

WHERE ea_accno = :ea_accno;

if (SQLCODE < 0)      /* some error occurs */

{

printf ([%s--%ld], fail to update[%d]\n,

__FILE__, __LINE__, SQLCODE);

return (-1);

}

return (0);

}

6.1.2 选择(select

通用语法:

        INTO var-list

        FROM [OUTER] table-name [table-alias] [,...]

        [WHERE condition]

        [GROUP BY column-list] [HAVING condition]

        [ORDER BY column-name [ASC | DESC],...]

        [INTO TEMP table-name] [WITH NO LOG]

该语句适用于已知结果集只有一条记录的查询。如果通过此语句得到的结果集包含多条记录,则SQLCODE会置成一个负数来指示错误。

如果某一字段可能为空值(NULL),则应该为此字段指定一个指示器变量,查询执行后,若该指示器变量小于0,则此字段为空值。例如,下例查询保证金分户帐的利息,如果利息为空值则认为等于0

int get_int(char *accno, double *int)

{

EXEC SQL BEGIN DECLARE SECTION;

char         ea_accno[17];

double       ea_enterest;

 

int          ea_enterest_i;       /* indicator */

EXEC SQL END DECLARE SECTION;

 

strcpy (ea_accno, accno);

ea_enterest_i = 0;

EXEC SQL SELECT ea_enterest INTO :ea_enterest :ea_enterest_i

FROM ca_eacc

WHERE ea_accno = :ea_accno;

if (SQLCODE)

{

printf ([%s--%ld], fail to select[%d--%s]\n,

__FILE__, __LINE__, SQLCODE, accno);

return (-1);

}

if (ea_enterest_i < 0)  ea_enterest = 0;

*int = ea_enterest;

return (0);

}

6.1.3 更改(update

通用语法:

EXEC SQL UPDATE table-name SET {column-name = variable [,...]

        | {(col-list) | *} = (var-list)}

        [WHERE condition]

6.1.4 插入(insert

EXEC SQL INSERT INTO table-name [(column-list)]

{

        VALUES (var-list)

        |

        SELECT-statement

}

6.1.5 删除(delete

EXEC SQL DELETE FROM table-name [WHERE condition]

6.1.6 游标

如果结果集可能包含多条记录,则应该使用游标(CURSOR)来执行查询。使用游标的步骤通常如下所示:

☆ 申明游标

☆ 打开游标

☆ 推进游标,读取记录

☆ 关闭游标

下例从保证金分户帐中读取机构代码为5210642188的所有帐户的帐号、帐户名称及余额:

int PrintEacc(char *org)

{

EXEC SQL BEGIN DECLARE SECTION;

char          ea_org[11];

char          ea_accno[17];

char          ea_name[11];

double        ea_eamt;

 

int           ea_eamt_i;

EXEC SQL END DECLARE SECTION;

 

/* 申明游标 */

EXEC SQL DECLARE eacc_cur CURSOR FOR

SELECT ea_accno, ea_name, ea_eamt

FROM ca_eacc

WHERE ea_org = :ea_org;

if (SQLCODE)

{

printf ([%s--%ld], fail to declare cursor[%d]\n,

__FILE__, __LINE__, SQLCODE);

return (-1);

}

 

/* 设置机构代码并打开游标 */

strcpy (ea_org, org);

EXEC SQL OPEN eacc_cur;

if (SQLCODE)

{

printf ([%s--%ld], fail to open cursor[%d--%s]\n,

__FILE__, __LINE__, SQLCODE, org);

return (-1);

}

 

while (1)

{

/* 设置初值 */

memset (ea_accno, \0, sizeof(ea_accno));

memset (ea_name, \0, sizeof(ea_name));

ea_eamt = ea_eamt_i = 0;

/* 推进游标 */

EXEC SQL FETCH eacc_cur INTO

:ea_accno, :ea_name, :ea_eamt :ea_eamt_i;

if (SQLCODE == SQLNOTFOUND)  break;   /* 结果集末尾 */

if (SQLCODE)

{

printf ([%s--%ld], fail to fetch cursor[%d--%s]\n,

__FILE__, __LINE__, SQLCODE, org);

EXEC SQL CLOSE eacc_cur;      /* 关闭游标 */

EXEC SQL FREE eacc_cur;       /* 释放游标资源 */

return (-1);

}

if (ea_eamt_i < 0) ea_eamt = 0;

printf (accno[%s], name[%s], amount[%16.2lf]\n,

ea_accno, ea_name, ea_eamt);

}

EXEC SQL CLOSE eacc_cur;      /* 关闭游标 */

EXEC SQL FREE eacc_cur;       /* 释放游标资源 */

return (0);

}

6.1.7 选择及关闭数据库

EXEC SQL DATABASE dabase-name;

EXEC SQL CLOSE DATABASE;

程序编译

ESQL源程序通常以.ec做为后缀,通过编译选项的选择,ESQL编译器可将.ec源代码预处理成.c源程序(-e),或者编译成.o文件(-c),或者编译链接成可执行文件(默认)。例如,如下的makefile和包含文件可将指定的文件编译成可执行代码:

包含文件:

# makefile header

TRANHOME=/home/credit/transform

TRANBIN=$(TRANHOME)/bin

OBJPATH= $(TRANHOME)/obj

 

# compiler

CC=   xlc_r4

CC=   cc

ESQL= esql

 

# flags

PREFLAG=  -g  -DDEBUGON

LINKFLAGS=-g  -DDEBUGON -static

 

# libarary

LIB=-lFit -lsql  -lcurses -lc -ldl -lreportall

 

# path

LIBDIR=-L. -L$(TRANHOME)/lib \

 -L${INFORMIXDIR}/lib/esql -L${INFORMIXDIR}/lib

INCLUDE= -I${TRANHOME}/include -I${INFORMIXDIR}/incl \

  -I${INFORMIXDIR}/incl/esql

 

OBJ=$(EC_SRC:.ec=.o) $(C_SRC:.c=.o)

EXEC=$(SC_SRC:.sc=.exe)

 

# rule

.SUFFIXES: .ec .o .sc .exe .c .o

.c.o:

  @echo "\tcompiling " $< "\t....................\c"

  @$(CC) -c $(PREFLAG) $(INCLUDE) $*.c

  @echo "OK"

.ec.o:

  @echo "\tcompiling " $< "\t....................\c"

  @$(ESQL) -e $(PREFLAG) $(INCLUDE) $<

  @$(CC) -c $(PREFLAG) $(INCLUDE) $*.c

  @rm -f $*.c

  @echo "OK"

.sc.exe:

  @echo "\tcompiling " $< "\t....................\c"

  @cp $< $*.ec

  @$(ESQL) -e $(PREFLAG) $(INCLUDE) $*.ec

  @$(ESQL) -c $(PREFLAG) $(INCLUDE) $*.c

  @$(ESQL) $(LINKFLAGS) ${INCLUDE} -o $@ $*.o \

 $(FOREIGNOBJ) $(LIBDIR) ${LIB}

  @cp $*.exe $*

  @rm -f $*.ec $*.c $*.o

  @echo "OK"

 

# rule

all:$(OBJ) $(EXEC)

  @echo "\t\tdoing with object file\t\t............\c"

  @if [ "$(OBJ)" != " " ] ; then \

      chmod 644 $(OBJ) ; \

      cp $(OBJ) $(OBJPATH) ; \

  fi

  @echo "OK"

  @echo "\t\tdoing with executable file\t............\c"

  @for varible in $(SC_SRC:.sc=) null_file ; \

  do  \

      if  test -f $$varible  ; then  \

          chmod 755 $$varible ; \

          mv $$varible $(TRANBIN) ; \

      fi; \

  done

  @echo "OK"

 

clean:

  @echo "\tremoving files\t....................\c"

  @rm  -f $(C_SRC:.c=.o) $(EC_SRC:.ec=.o) $(EC_SRC:.ec=.c)

  @rm  -f $(SC_SRC:.sc=.o) $(SC_SRC:.sc=.c) $(SC_SRC:.sc=.ec)

  @rm  -f $(SC_SRC:.sc=.exe) $(SC_SRC:.sc=)

  @echo "OK"

makefile文件:

# file list

EC_SRC= tp_main.ec

SC_SRC= tp_acctyp.sc tp_cardacc.sc tp_cardproc.sc \

        tp_cardser.sc tp_eacc.sc tp_iacc.sc \

        tp_idetail.sc tp_kbacc.sc \

        tp_ointer.sc tp_procacc.sc tp_subject.sc tp_sys.sc

C_SRC=

 

include ../mkhead


阅读(1957) | 评论(0) | 转发(1) |
0

上一篇:数据库基础

下一篇:第七章、通讯中间件

给主人留下些什么吧!~~