Home  >  Article  >  Database  >  嵌入式SQL与主语言的通信_MySQL

嵌入式SQL与主语言的通信_MySQL

WBOY
WBOYOriginal
2016-06-01 13:51:503074browse
将SQL嵌入到高级语言中混合编程,程序中会含有两种不同计算模型的语句:
 (1)SQL语句:描述性的面向集合的语句;负责操纵数据库
 (2)高级语言语句:过程性的面向记录的语句;负责控制程序流程。
工作单元之间的通信方式:
 1. SQL通信区:向主语言传递SQL语句的执行状态信息;主语言能够据此控制程序流程
 2. 主变量:
  (1)主语言向SQL语句提供参数。
  (2)将SQL语句查询数据库的结果交主语言进一步处理。
 3. 游标:解决集合性操作语言与过程性操作语言的不匹配。
一、SQL通信区
  SQLCA: SQL Communication Area。SQLCA是一个数据结构
  SQLCA的用途:
  SQL语句执行后,DBMS反馈给应用程序信息
   (1)描述系统当前工作状态
   (2)描述运行环境
  这些信息将送到SQL通信区SQLCA中,应用程序从SQLCA中取出这些状态信息,据此
  决定接下来执行的语句。
  SQLCA的使用方法:
   用EXEC SQL INCLUDE SQLCA加以定义。SQLCA中有一个存放每次执行SQL语句后返回
   代码的变量SQLCODE。如果SQLCODE等于预定义的量SUCCESS,则表示SQL语句成功,
   否则表示出错;应用程序每执行完一条SQL 语句之后都应该测试一下SQLCODE的值,
   以了解该SQL语句执行情况并做相应处理。
  例:在执行删除语句DELETE后,不同的执行情况,SQLCA中有不同的信息:
        违反数据保护规则,操作拒绝
        没有满足条件的行,一行也没有删除
        成功删除,并有删除的行数
        无条件删除警告信息
        由于各种原因,执行出错
二、主变量
  嵌入式SQL语句中可以使用主语言的程序变量来输入或输出数据。在SQL语句中使用的
  主语言程序变量简称为主变量(Host Variable)。
  主变量的类型:
   输入主变量:由应用程序对其赋值,SQL语句引用。
   输出主变量:由SQL语句赋值或设置状态信息,返回给应用程序。
  一个主变量有可能既是输入主变量又是输出主变量。
  一个主变量可以附带一个指示变量(Indicator Variable)
  指示变量一个整型变量,用来“指示”所指主变量的值或条件。
  指示变量的用途:输入主变量可以利用指示变量赋空值;输出主变量可以利用指示
  变量检测出是否空值,值是否被截断
  在SQL语句中使用主变量和指示变量的方法
   (1) 说明主变量和指示变量
         BEGIN DECLARE SECTION
         ......... 
         ......... (说明主变量和指示变量)
         .........
         END DECLARE SECTION
   
 (2) 使用主变量
    说明之后的主变量可以在SQL语句中任何一个能够使用表达式的地方出现
    为了与数据库对象名(表名、视图名、列名等)区别,SQL语句中的主变
    量名前要加冒号(:)作为标志。
  (3) 使用指示变量
    指示变量前也必须加冒号标志
    必须紧跟在所指主变量之后
    在SQL语句之外(主语言语句中)使用主变量和指示变量的方法:
    可以直接引用,不必加冒号。
三、游标(cursor)
  游标是系统为用户开设的一个数据缓冲区,存放SQL语句的执行结果。每个游标区都有
  一个名字,用户可以用游标逐一获取记录,并赋给主变量,交由主语言进一步处理。
  为什么要使用游标: 
   SQL语言与主语言具有不同数据处理方式
   SQL语言是面向集合的,一条SQL语句原则上可以产生或处理多条记录
  主语言是面向记录的,一组主变量一次只能存放一条记录,仅使用主变量并不能完全
  满足SQL语句向应用程序输出数据的要求。
  嵌入式SQL引入了游标的概念,用来协调这两种不同的处理方式下面用个程序详解

#include
#include


EXEC SQL BEGIN DECLARE SECTION; /*主变量说明开始*/ 
char deptname[64];
char HSno[64];
char HSname[64]; 
char HSsex[64];
int HSage;
int NEWAGE;
long SQLCODE;
EXEC SQL END DECLARE SECTION;     /*主变量说明结束*/

EXEC SQL INCLUDE sqlca;               /*定义SQL通信区*/

/*************************************************************************/

int main(void)                           /*C语言主程序开始*/
{
int count = 0;
char yn;                              /*变量yn代表yes或no*/
printf("Please choose the department name(CS/MA/IS): "); 
scanf("%s", deptname);                 /*为主变量deptname赋值*/
EXEC SQL CONNECT TO HP-08D6CXF128B/SQL2000 USER sa;         /*连接数据库TEST*/
EXEC SQL DECLARE SX CURSOR FOR   /*定义游标*/
SELECT Sno, Sname, Ssex, Sage   /*SX对应语句的执行结果*/
FROM Student
WHERE SDept = :deptname;
EXEC SQL OPEN SX;        /*打开游标SX便指向查询结果的第一行*/

for ( ; ; )                       /*用循环结构逐条处理结果集中的记录*/

EXEC SQL FETCH SX INTO :HSno, :HSname, :HSsex,:HSage;
      /*推进游标,将当前数据放入主变量*/
if (sqlca->sqlcode != 0)     /* sqlcode != 0,表示操作不成功*/
break;                /*利用SQLCA中的状态信息决定何时退出循环*/
if(count++ == 0)             /*如果是第一行的话,先打出行头*/
printf("/n%-10s %-20s %-10s %-10s/n", "Sno", "Sname", "Ssex", "Sage");
printf("%-10s %-20s %-10s %-10d/n", HSno, HSname, HSsex, HSage); 
     /*打印查询结果*/
printf("UPDATE AGE(y/n)?"); /*询问用户是否要更新该学生的年龄*/
do{                     
    scanf("%c",&yn);
}
while(yn != 'N' && yn != 'n' && yn != 'Y' && yn != 'y');
if (yn == 'y' || yn == 'Y')                 /*如果选择更新操作*/
{
   printf("INPUT NEW AGE:");
   scanf("%d",&NEWAGE);          /*用户输入新年龄到主变量中*/
   EXEC SQL UPDATE Student            /*嵌入式SQL*/
   SET Sage = :NEWAGE
   WHERE CURRENT OF SX ;
}                 /*对当前游标指向的学生年龄进行更新*/
}

EXEC SQL CLOSE SX;           /*关闭游标SX不再和查询结果对应*/
EXEC SQL COMMIT WORK;                           /*提交更新*/
EXEC SQL DISCONNECT TEST;                  /*断开数据库连接*/
}

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn