- 浏览: 865906 次
- 性别:
- 来自: 济南
文章分类
- 全部博客 (280)
- java相关 (29)
- linux系统 (55)
- ipsec (0)
- ssl (3)
- 信息安全 (13)
- web相关 (35)
- windows (9)
- c,c++ (14)
- log4j (3)
- hibernate (8)
- sqlite (1)
- 程序人生 (2)
- js (2)
- 生活点滴 (3)
- 网络相关 (14)
- 问题积累 (15)
- 数据库相关 (27)
- 软件测试 (2)
- PKI相关 (2)
- 程序设计 (7)
- 犄角旮旯 (0)
- 杂七杂八 (0)
- 硬件相关 (14)
- 防火墙 (2)
- 电子商务 (2)
- 多媒体相关 (1)
- 内存管理 (4)
- 面向对象 (1)
- csp (1)
- 驱动开发 (3)
- 移动开发 (2)
- openssl多线程实例 (1)
最新评论
-
xiaoyao3857:
博主很有探索精神嘛,学习了
Linux主机名Hostname详解 -
hiskyrisa:
言简意赅,好文章。
Flex是什么 -
layznet:
犯了类似错误。使用的是derby数据库。driverClass ...
java.sql.SQLException: No suitable driver -
idision:
你好,文章有一句createSubjectKeyId(keyT ...
bouncycastle 产生证书 -
zheng12tian:
代码有全的不?只贴一部分,,,,
在LOG4J中把日志写入远程数据库
5.3 嵌入SQL的处理过程
INFORMIX的预编译器为esql。嵌入SQL包含一些组件:嵌入SQL的库文件,提供访问数据库服务器、
操作各种数据类型、出错信息的处理等函数。嵌入SQL的头文件(UNIX环境:$INFORMIXDIR/incl/esql下,WINDOWS环
境:%INFORMIXDIR%\incl\esql下),提供程序用的数据结构、常数和宏的定义信息。Esql是预编译器。UNIX系统下,是
finderr程序获得INFORMIX的错误信息,WINDOWS平台下是find error获得错误信息。还有一些GLS
locale文件,提供一些特定的locale信息。在WINDOWS平台下,还有另外一些文件,如:setnet
32、ilogin、regcopy、esqlmf程序。
创建嵌入SQL/C的程序的一般步骤:程序的后缀可以是.ec或.ecp。
1、定义宿主变量。
2、访问数据库。
3、操作。
4、完成后,使用esql命令来预编译。如:esql
demo1.ec。在预编译后,程序中只有C语言语句,它们都可以为C语言的编译器所识别。所以,可以按照一般的方法进行编译和连接,但在将SQL语句转
换以后,在C语言程序中,又引入了许多一般的C语言系统所没有的结构、变量和函数,因此应该设置INCLUDE和LIB的设置。最后生成的可执行文件。
5.4 动态SQL语言
所谓静态SQL的编程方法,就是指在预编译时SQL语句已经基本确定,即访问的表或视图名、访问的列等信息已经确定。但是,有时整个SQL语句要到执行的时候才能确定下来,而且SQL语句所访问的对象也要到执行时才能确定。这就需要通过动态SQL语句完成。动态SQL语句的处理步骤是:
1、组合SQL语句。
2、PREPARE。PREPARE语句是动态SQL语句独有的语句。其语法为:
PREPARE 语句名 FROM 宿主变量|字符串
该语句接收含有SQL语句串的宿主变量,并把该语句送到DBMS。DBMS编译语句并生成执行计划。在语句串中包含一个“?”表明参数,当执行语句
时,DBMS需要参数来替代这些“?”。PREPRARE执行的结果是,DBMS用语句名标志编译后的语句。在执行SQL语句时,EXECUTE语句后面
是这个语句名。请看下面这个例子:
EXEC SQL prepare slct_id from
'select company from customer where customer_num = ?';
可以通过SQLCA检查PREPARE操作是否成功。
3、EXECUTE或OPEN。
EXECUTE语句的语法如下:
EXECUTE 语句名 USING 宿主变量 | DESCRIPTOR 描述符名
它的作用是,请求DBMS执行PREPARE语句准备好的语句。当要执行的动态语句中包含一个或多个参数标志时,在EXECUTE语句必须为每一个参数提
供值。这样的话,EXECUTE语句用宿主变量值逐一代替准备语句中的参数标志(“?”),从而,为动态执行语句提供了输入值。
如果是多行查询,则使用游标,使用OPEN USING语句传递参数;如果是单行查询,则使用SELECT
INTO。如果是修改数据:则使用EXECUTE
USING语句。如果知道参数个数,就可以使用宿主变量。如果不知道参数个数,则必须使用DESCRIBE语句。下表总结了动态SQL语句的处理方法:
语句类型是否有输入参数执行的方法
INSERT、DELETE、UPDATE没有EXECUTE
INSERT、DELETE、UPDATE有(数据类型和个数确定)EXECUTE …USING
INSERT、DELETE、UPDATE有(数据类型和个数不确定)EXECUTE...USINGSQL DESCRIPTOR或EXECUTE...USINGDESCRIPTOR
SELECT(返回多行)无OPEN
SELECT(返回多行)有(数据类型和个数确定)OPEN…USING
SELECT(返回多行)有(数据类型和个数不确定)OPEN...USINGSQL DESCRIPTOR或OPEN...USINGDESCRIPTOR
SELECT(返回一行)无EXECUTE...INTO
SELECT(返回一行,但是返回的数据类型和个数不确定)无EXECUTE...INTODESCRIPTOR或EXECUTE...INTOSQL DESCRIPTOR
SELECT(返回一行)有EXECUTE...INTO...USING
SELECT(返回一行,但是返回的数据类型和个数不确定)有EXECUTE...INTO...USING SQLDESCRIPTOR或EXECUTE...INTO...USINGDESCRIPTOR 4、释放资源。
5.4.1 SQLDA
可以通过SQLDA为嵌入SQL语句提供输入数据和从嵌入SQ语句中输出数据。理解SQLDA的结构是理解动态SQL的关键。
我们知道,动态SQL语句在编译时可能不知道有多少列信息。在嵌入SQL语句中,这些不确定的数据是通过SQLDA完成的。SQLDA的结构非常灵活,在
该结构的固定部分,指明了多少列等信息(如下图中的sqld=2,表示为两列信息),在该结构的后面,有一个可变长的结构(SQLVAR结构),说明每列
的信息。
SQLDA结构
Sqld=2
sqlvar
Desc_name
Desc_occ
Desc_next
Sqltype=500
Sqllen
sqldata
…..
Sqltype=501
Sqllen
Sqldata
….. 图6-6 SQLDA结构示例
具体SQLDA的结构在sqlda.h中定义,是:
struct sqlvar_struct
{
short sqltype;/* variable type*/
short sqllen;/* length in bytes*/
char *sqldata;/* pointer to data*/
short *sqlind;/* pointer to indicator*/
char *sqlname;/* variable name*/
char *sqlformat;/* reserved for future use */
short sqlitype;/* ind variable type*/
short sqlilen;/* ind length in bytes*/
char *sqlidata;/* ind data pointer*/
}; struct sqlda
{
short sqld;
struct sqlvar_struct *sqlvar;
char desc_name[19];/* descriptor name */
short desc_occ;/* size of sqlda structure */
struct sqlda *desc_next;/* pointer to next sqlda struct */
}; #endif /* _SQLDA */
从上面这个定义看出,SQLDA是一种由三个不同部分组成的可变长数据结构。位于SQLDA开端的sqldaid用于标志该SQLDA描述了多少列的信
息;而后是一个或多个sqlvar结构
,用于标志列数据。当用SQLDA把参数送到执行语句时,每一个参数都是一个sqlvar结构;当用SQLDA返回输出列信息时,每一列都是一个
sqlvar结构。第三部分是SQLDA结构的描述信息部分。具体每个元素的含义为:
lSqld。目前使用的sqlvar结构的个数。即输出列的个数。
lSqlvar。指向sqlvar_struct结构。 即指向描述第一列信息的sqlvar结构。
lDesc_name。Sqlda的名称。
lDesc_occ。Sqlda结构的大小。
lDesc_next。指向下一个SQLDA结构。
lSqltype。代表参数或列的数据类型。它是一个整数数据类型代码。具体每个整数的含义见第二节。
l Sqllen。代表传送数据的长度。如:2,即代表二字节整数。如果是字符串,则该数据为字符串中的字符数量。
lSqldata。指向数据的地址。注意,仅仅是一个地址。
lSqlind。代表是否为NULL。如果该列不允许为NULL,则该字段不赋值;如果该列允许为NULL,则:该字段若为0,表示数据值不为NULL,若为-1,表示数据值为NULL。
lSqlname。代表列名或变量名。它是一个结构。包含length和data。Length是名字的长度;data是名字。
lSqlformat。保留为以后使用。
lSqlitype。指定用户定义的指示符变量的数据类型。
lSqlilen。指定用户定义的指示符变量的长度。
lSqlidata。指向用户定义的指示符变量所存放的数据。 下面这个ADHOC程序非常经典,演示了SQLDA的作用。模拟一个不确定的查询,然后通过SQLDA来获得数据,并打印出来。
EXEC SQL include locator.h;
EXEC SQL include sqltypes.h;
#define BLOBSIZE 32276;
main()
{
int i = 0;
int row_count;
/**** Step 1: 声明一个SQLDA结构,来存放查询的数据 ********/
struct sqlda *da_ptr;
/*连接到数据库服务器*/
EXEC SQL connect to 'stores7';
if ( SQLCODE < 0 )
{ printf("CONNECT failed: %d\n", SQLCODE)
exit(0);
}
/* 创建一个临时表,模拟一个不确定列和表的环境*/
EXEC SQL create table blob_tab (int_col integer, blob_col byte);
/* load_db函数是往blob_tab表插入数据,读者不用关心它的代码*/
load_db();
/* PREPARE查询语句 */
EXEC SQL prepare selct_id 'select * from tab1';
/* Step 2: 使用describe函数完成两个功能:一是为sqlda分配空间, 二是获取语句信息,并存放在SQLDA结构中。*/
EXEC SQL describe selct_id into da_ptr;
/* Step 3: 初试化sqlda结构,如:为列分配空间,改变数据类型等。*/
row_size = init_sqlda(da_ptr, 0);
/* 为PREPARE的SELECT语句声明和打开游标*/
EXEC SQL declare curs for selct_id;
EXEC SQL open curs;
while (1)
{
/* Step 4: 执行fetch操作,将一行数据存放在sqlda结构中*/
EXEC SQL fetch curs using descriptor da_ptr;
/* 是否到达最后一行?,若是,则退出。 */
if ( SQLCODE == SQLNOTFOUND )
break;
/* Step 5: 从SQLDA中打印数据,使用sqlca.sqlerrd[2]来获得查询的行数*/
printf("\n===============\n");
printf("FETCH %d\n", i++);
printf("===============");
print_sqlda(da_ptr, ((FetArrSize == 0) ? 1 : sqlca.sqlerrd[2]));
/* Step 6: 循环执行FETCH,直到处理完所有的行(SQLCODE为SQLNOTFOUND)*/
}
/* Step 7: 释放申请的内存空间,如游标、SQLDA、创建的临时表等*/
EXEC SQL free selct_id;
EXEC SQL close curs;
EXEC SQL free curs;
free_sqlda(da_ptr);
cleanup_db();
}
/************************************************************************
* 函数: init_sqlda()
* 作用: 为SQLDA申请空间
* 返回值: 0 正确,否则有错误
************************************************************************/
int init_sqlda(in_da, print)
struct sqlda *in_da;
int print;
{
int i, j, row_size=0, msglen=0, num_to_alloc;
struct sqlvar_struct *col_ptr;
loc_t *temp_loc;
char *type;
if (print)
printf("columns: %d. ", in_da->sqld);
/* Step 1: 获得一行数据的长度 */
for (i = 0, col_ptr = in_da->sqlvar; i < in_da->sqld; i++, col_ptr++)
/* msglen变量存放查询数据的所有列的长度和。*/
msglen += col_ptr->sqllen; /* get database sizes */
/* 为col_ptr->sqllen 重新赋值,该值是在C下的大小。如:在数据库中的字符串,在C中应该多一个字节空间来存放NULL的结束符。*/
col_ptr->sqllen = rtypmsize(col_ptr->sqltype, col_ptr->sqllen);
/*row_size变量存放了在C程序中的所有列的长度和。这个值是应用程序为存放一行数据所需要申请的内存空间*/
row_size += col_ptr->sqllen;
}
if (print) printf("Total row size = %d\n", row_size);
/* Step 2: 设置FetArrSize值*/
if (FetArrSize == -1) /* if FetArrSize not yet initialized */
{
if (FetBufSize == 0) /* if FetBufSize not set */
FetBufSize = 4096; /* default FetBufSize */
FetArrSize = FetBufSize/msglen;
}
num_to_alloc = (FetArrSize == 0)? 1: FetArrSize;
/* 设置sqlvar_struct结构中的数据类型为相应的C的数据类型*/
for (i = 0, col_ptr = in_da->sqlvar; i < in_da->sqld; i++, col_ptr++)
{
switch(col_ptr->sqltype)
{
case SQLCHAR:
type = "char ";
col_ptr->sqltype = CCHARTYPE;
break;
case SQLINT:
type = "int ";
col_ptr->sqltype = CINTTYPE;
break;
case SQLBYTES:
case SQLTEXT:
if (col_ptr->sqltype == SQLBYTES)
type = "blob ";
else
type = "text ";
col_ptr->sqltype = CLOCATORTYPE;
/* Step 3 :只有数据类型为TEXT 和BLOB时,才执行。为存放TEXT 或BYTE列数据申请空间*/
temp_loc = (loc_t *)malloc(col_ptr->sqllen * num_to_alloc);
if (!temp_loc)
{
fprintf(stderr, "blob sqldata malloc failed\n");
return(-1);
}
col_ptr->sqldata = (char *)temp_loc;
/* Step 4:只有数据类型为TEXT 和BLOB时,才执行。初试化loc_t结构*/
byfill(temp_loc, col_ptr->sqllen*num_to_alloc ,0);
for (j = 0; j< num_to_alloc; j++, temp_loc++)
{
temp_loc->loc_loctype = LOCMEMORY;
temp_loc->loc_bufsize = BLOBSIZE;
temp_loc->loc_buffer = (char *)malloc(BLOBSIZE);
if (!temp_loc->loc_buffer)
{
fprintf(stderr, "loc_buffer malloc failed\n");
return(-1);
}
temp_loc->loc_oflags = 0; /* clear flag */
} /* end for */
break;
default: /* 其他数据类型*/
fprintf(stderr, "not yet handled(%d)!\n", col_ptr->sqltype);
return(-1);
} /* switch */
/* Step 5: 为指示符变量申请空间*/
col_ptr->sqlind =
(short *) malloc(sizeof(short) * num_to_alloc);
if (!col_ptr->sqlind)
{
printf("indicator malloc failed\n");
return -1;
/* Step 6 :为存放非TEXT 和BLOB的数据类型的sqldata申请空间.注意的是,申请的地址是(char *),在输出数据时,要按照相应的数据类型做转换。*/
if (col_ptr->sqltype != CLOCATORTYPE)
{
col_ptr->sqldata = (char *) malloc(col_ptr->sqllen * num_to_alloc);
if (!col_ptr->sqldata)
{
printf("sqldata malloc failed\n");
return -1;
}
if (print)
printf("column %3d, type = %s(%3d), len=%d\n", i+1, type,
col_ptr->sqltype, col_ptr->sqllen);
} /* end for */
return msglen;
}
/***********
发表评论
-
mysql 安装注意
2010-07-12 21:07 866mysql 远程连接赋予权限: GRANT ALL PRIV ... -
Windows和Linux系统下面MySQL的大小写敏感性不同
2010-04-21 15:00 2055同样的建表脚本,在windows下所有的表名都成了小写的了,在 ... -
关闭Mysql日志功能
2009-08-04 17:47 1590Cacti服务器使用有一段时间了,发现在 /usr/loca ... -
ESQL编程使用说明
2009-07-30 20:51 2031ESQL编程使用说明 ... -
ESQL/C资料(完全版)三
2009-07-30 20:47 2176第四节 ORACLE数据库的嵌 ... -
ESQL/C资料(完全版)二
2009-07-30 20:46 1953第三节 IBM DB2嵌入SQL语言 DB2支持SQL ... -
ESQL/C资料(完全版)一
2009-07-30 20:45 2539第六章 嵌入式SQL(E-SQL)简介 ... -
Mysql5的auto Reconnect错误
2009-07-28 09:10 4977一、解决方案一 最近 ... -
Mysql JDBC URL中几个重要参数说明
2009-07-28 08:57 2960mysql JDBC Driver 常用的有两个,一个是gj ... -
Linux平台下修正MySQL中文乱码问题
2009-07-20 16:49 1749操作系统环境: RHEL4.6 ... -
如何将syslogng的日志写入MySQL数据库
2009-07-20 11:24 3480如何将syslogng的日志写入MySQL数据库 <! ... -
shell自动连接mysql后进行查询操作的方法
2009-07-20 11:14 96361.需求,自动登录mysql(root:root,passwd ... -
用C语言操作MySQL数据库,进行连接、插入、修改、删除等操作
2009-07-20 11:07 2347很多人用到MySQL来开发一些项目,有时为了性能,我们会直接 ... -
mysql 5.X 迁移linux上,表名大小写敏感问题!
2009-07-18 17:39 2361mysql数据库,库名以目录名存在,表名以文件名(后缀为.fr ... -
mysql常用经典操作
2009-07-18 15:42 940.连接服务器 mysql -u cnscn ... -
绿色数据库
2009-07-17 23:20 1315如今,由于网络应用的飞速发展、多媒体数据的日益增长、视频音频 ... -
linux下mysql的最常用的操作指令_创建用户、备份和还原数据库
2009-07-17 08:55 27121]如何创建mysqld数据库的管理用户? 数据库安装好后, ... -
Linux操作系统下MySQL数据库的使用方法
2009-07-17 08:54 1034一、连接MYSQL: 格式: mysql -h主机 ... -
org.gjt.mm.mysql.Driver和com.mysql.jdbc.Driver的 区别
2009-07-15 11:42 1996org.gjt.mm.mysql.Driver是早期的驱动名称 ... -
安装 MySQL、MySQL GUI Tools
2009-07-14 14:57 2472文/李红军 http://hongjunli.blogjava ...
相关推荐
ESQL/C 嵌入式 SQL 资料(完全版) ESQL/C 嵌入式 SQL 是一种特殊的编程语言,它将 SQL 语句直接嵌入到程序的源代码中,用于访问数据库。ESQL/C 嵌入式 SQL 语言是基于 SQL 语言的扩展,它提供了一个可靠的解决方案...
介绍了如何使用Microsoft SQL Server 2000和VC开发数据库(ESQL/C 嵌入式SQL)
ESQL/C是特定于C语言的嵌入式SQL版本。 在ESQL/C中,有几个关键的概念和组成部分: 1. **嵌入SQL程序的组成元素**:一个嵌入式SQL程序由宿主语言代码和SQL语句组成。宿主语言负责程序的控制流,而SQL语句用于与...
- **INFORMIX-4GL 快速开发版**:无需 C 编译器即可编译 INFORMIX-4GL 程序,显著减少编译时间。 - **INFORMIX-4GL 交互调试器**:允许开发者在应用程序运行过程中调试 INFORMIX-4GL 代码。 - **INFORMIX-4GL/RF*...
#### 四、ESQL语法与示例 ESQL允许开发者在C语言代码中直接插入SQL语句。例如: ```c #include char *query = "SELECT * FROM table_name"; db_query(db, query, &result, NULL); ``` 在此示例中,`db_query`...
在 ESQL/C 的上下文中,SQL 语句被预编译器处理,转换成宿主语言可识别的函数调用,然后由对应的编译器(如 C 编译器)编译为可执行程序。 在 ANSI/ISO 标准下,不同数据库厂商都支持嵌入式 SQL,但每个厂商可能会...
### ESQL/C资料(完全版) #### 第一节 什么是嵌入SQL语言? **1.1 嵌入SQL程序的组成元素** 嵌入式SQL(Embedded SQL, ESQL)是一种将SQL语句直接嵌入到高级编程语言(如C语言)中的方法,允许开发者直接在应用...
SQL是所有数据库操作的基础,而ESQL/C则是将SQL语句嵌入到C语言程序中的一种方法。这使得开发者可以在C语言中直接执行复杂的数据库操作。 - **提高系统效率的几点建议** 提高系统效率的方法包括优化查询语句、...
伴随着数据库的发展,Informix还提供了一系列开发工具,如4GL和ESQL/C等,这些工具为开发者提供了强大的数据库应用开发能力,极大地提升了开发效率和应用程序的性能。 #### 二、数据库管理与系统维护 数据库管理...
- `sybase-ase-11.0.3.3-1.i386.rpm`:包含了Sybase ASE 11.0.3.3的主要组件,包括SQL Server、Backup Server、Sybinit和Sybmon,以及OpenClient 10.0.4和OpenServer,还有ESQL/C接口。 - `sybase-doc-11.0.3.3-1....
4. **4GL(第四代编程语言)**:Informix 自有的 4GL 语言,如 Informix-4GL 和 ESQL/C,提供了高效开发数据库应用的环境。 **四、Informix 高级特性** 1. **分布式数据库**:Informix 支持分布式数据库系统,允许...
对于应用开发工具,Informix提供了一系列基于4GL(第四代编程语言)的产品,包括I-SQL、4GLRDS、4GLCCOMPILER、4GLID和ESQL/C等。这些工具支持开发者创建基于字符界面的数据库应用程序。随着技术的发展,Informix还...
### 控制数据库服务 在IT领域,特别是数据库管理与应用开发方面,掌握如何有效地控制数据库服务至关重要。...了解这些函数的工作原理对于任何从事Informix-ESQL/C应用开发的工程师来说都是非常有价值的。
#### 完整问题与答案集合 Pass4sure提供的106个问题及答案集合覆盖了000-315考试的所有方面,帮助考生全面掌握所需知识。以下是几个具体的知识点: 1. **构建无WSDL访问的消息流**: - **问题**: 一个WMB V6.1...
- **丰富的客户端接口**:支持 ODBC、JDBC、Python、Perl、Tcl、C/C++、ESQL 等多种编程语言的客户端接口。 - **跨平台支持**:支持多种操作系统和硬件架构,包括 Windows、Linux、macOS 等。 ### PostgreSQL 的...
Sybase IQ 15.4中文手册详细介绍了该版本的命令和系统参数,对于数据库管理员和开发者而言,这是极为重要的参考资料。手册涵盖了SQL语句的使用,包括数据定义语言(DDL)、数据操纵语言(DML)和事务控制语句等。...