嵌入式SQL嵌入式SQL(英文: Embedded SQL)是一种将SQL语句直接写入C语言、COBOL、FORTRAN及Ada等编程语言源代码中的方法。藉此方法,可使得应用程式能夠存取以及處理資料。在这一方法中,将SQL文嵌入的目标源码的语言称为宿主语言。 在1986年发布的SQL86标准中定义了对于COBOL、FORTRAN及PI/L等语言的嵌入式SQL的规范。在1989年发布的SQL89规范中,定义了对于C语言的嵌入式SQL的规范。一些大型的数据库厂商发布的数据库产品中,都提供了对于嵌入式SQL的支持。比如Oracle、DB2等。 嵌入式SQL的工作原理提供对于嵌入式SQL的支持,需要数据库厂商除了提供DBMS之外,还必须提供一些工具。为了实现对于嵌入式SQL的支持,技术上必须解决以下4个问题[1]:
为了解决上述这些问题,数据库厂商需要提供一个嵌入式SQL的预编译器,把包含有嵌入式SQL文的宿主语言源码转换成纯宿主语言的代码。这样一来,源码即可使用宿主语言对应的编译器进行编译。通常情况下,经过嵌入式SQL的预编译之后,原有的嵌入式SQL会被转换成一系列函数调用。因此,数据库厂商还需要提供一些列函数库,以确保链接器能够把代码中的函数调用与对应的实现链接起来。 嵌入式SQL的扩展语法嵌入式SQL中除了可以执行标准SQL文之外,为了对应嵌入的需要,还增加了一些额外的语法成分。主要包含以下内容: 示例代码以下展示了用于连接PostgreSQL数据库并执行一次数据查询的嵌入式SQL源码(宿主语言为C语言): #include <stdio.h>
#include <stdlib.h>
#include <string.h>
EXEC SQL BEGIN DECLARE SECTION;
int var_c1;
char var_c2[21] = { 0x00 };
EXEC SQL END DECLARE SECTION;
int main(int argc, char* argv[])
{
/* 步骤1: 建立连接 */
EXEC SQL WHENEVER SQLERROR SQLPRINT; /* 声明异常发生时的处理动作统一为打印消息 */
EXEC SQL CONNECT TO postgres@localhost:5432 USER postgres/xxxx; /* 指定连接的目标数据库,用户名,密码 */
/* 步骤2: 利用游标执行查询 */
EXEC SQL DECLARE foo_bar CURSOR FOR SELECT c1, c2 FROM tb1; /* 声明一个游标使之用于执行SELECT文 */
EXEC SQL OPEN foo_bar; /* 打开游标从而使SELECT文被执行 */
EXEC SQL FETCH foo_bar INTO :var_c1, :var_c2; /* 获取一行数据 */
printf("C1: %d, C2: %s\n", var_c1, var_c2);
EXEC SQL CLOSE foo_bar; /* 关闭所打开的游标 */
/* 步骤3: 关闭连接 */
EXEC SQL DISCONNECT CURRENT;
return 0;
}
在Cygwin平台上,利用PostgreSQL 7.4.5所自带的嵌入式SQL的预编译器ECPG(版本号 3.1.1)进行预编译,生成的纯C语言代码如下所示: /* Processed by ecpg (3.1.1) */
/* These include files are added by the preprocessor */
#include <ecpgtype.h>
#include <ecpglib.h>
#include <ecpgerrno.h>
#include <sqlca.h>
#line 1 "ESQL_CONNECT.pgc"
/* End of automatic include section */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* exec sql begin declare section */
#line 6 "ESQL_CONNECT.pgc"
int var_c1 ;
#line 7 "ESQL_CONNECT.pgc"
char var_c2 [ 21 ] = { 0x00 } ;
/* exec sql end declare section */
#line 8 "ESQL_CONNECT.pgc"
int main(int argc, char* argv[])
{
/* 步骤1: 建立连接 */
/* exec sql whenever sqlerror sqlprint ; */
#line 13 "ESQL_CONNECT.pgc"
{ ECPGconnect(__LINE__, 0, "postgres@localhost:5432" , "postgres" , "asdf1234" , NULL, 0);
#line 14 "ESQL_CONNECT.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
#line 14 "ESQL_CONNECT.pgc"
/* 步骤2: 利用游标执行查询 */
/* declare foo_bar cursor for select c1 , c2 from tb1 */
#line 17 "ESQL_CONNECT.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, "declare foo_bar cursor for select c1 , c2 from tb1 ", ECPGt_EOIT, ECPGt_EORT);
#line 18 "ESQL_CONNECT.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
#line 18 "ESQL_CONNECT.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, "fetch foo_bar", ECPGt_EOIT,
ECPGt_int,&(var_c1),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(var_c2),(long)21,(long)1,21*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
#line 19 "ESQL_CONNECT.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
#line 19 "ESQL_CONNECT.pgc"
printf("C1: %d, C2: %s\n", var_c1, var_c2);
{ ECPGdo(__LINE__, 0, 1, NULL, "close foo_bar", ECPGt_EOIT, ECPGt_EORT);
#line 23 "ESQL_CONNECT.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
#line 23 "ESQL_CONNECT.pgc"
/* 步骤3: 关闭连接 */
{ ECPGdisconnect(__LINE__, "CURRENT");
#line 26 "ESQL_CONNECT.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
#line 26 "ESQL_CONNECT.pgc"
return 0;
}
支持嵌入式SQL的数据库产品以下列出支持嵌入式SQL的数据库产品以及各自支持的宿主语言 Oracle Database
IBM DB2IBM DB2的版本9中提供了对于C/C++,COBOL,Java等宿主语言的嵌入式SQL的支持。
参见注释
|