Loading AI tools
来自维基百科,自由的百科全书
嵌入式SQL(英文: Embedded SQL)是一種將SQL語句直接寫入C語言、COBOL、FORTRAN及Ada等程式語言原始碼中的方法。藉此方法,可使得應用程式能夠存取以及處理資料。在這一方法中,將SQL文嵌入的目標源碼的語言稱為宿主語言。
在1986年發佈的SQL86標準中定義了對於COBOL、FORTRAN及PI/L等語言的嵌入式SQL的規範。在1989年發佈的SQL89規範中,定義了對於C語言的嵌入式SQL的規範。一些大型的數據庫廠商發佈的數據庫產品中,都提供了對於嵌入式SQL的支持。比如Oracle、DB2等。
提供對於嵌入式SQL的支持,需要數據庫廠商除了提供DBMS之外,還必須提供一些工具。為了實現對於嵌入式SQL的支持,技術上必須解決以下4個問題[1]:
為了解決上述這些問題,數據庫廠商需要提供一個嵌入式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;
}
生成後的代碼中所調用的ECPGconnect等函數,由安裝PostgreSQL所自帶的ECPG庫(本例中為libecpg.so
)提供具體的實現,供連結器將其與上述C語言代碼編譯生成的目標文件進行連結。
以下列出支持嵌入式SQL的數據庫產品以及各自支持的宿主語言
IBM DB2的版本9中提供了對於C/C++,COBOL,Java等宿主語言的嵌入式SQL的支持。
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.