精华内容
下载资源
问答
  • 嵌入式SQL
    2021-05-26 02:25:39

    交互式SQL语言的局限性

    从使用者角度

    普通用户必须通过数据库应用程序来使用

    从SQL本身角度

    特别复杂的检索结果难以用一条交互式SQL语句完成,此时需要结合高级语言中经常出现的顺序,分支和循环结构帮助处理

    嵌入式SQL特性

    定义

    嵌入式SQL是将SQL嵌入到某一种高级语言之中,如C/C++,Java等 这种高级语言被称为宿主语言

    特性

    继承了高级语言的过程控制性

    结合了SQL语言的复杂结果集操作的非过程性

    为数据库操作者提供了安全可靠的操作方式:通过应用程序进行操作

    和交互式SQL的对比

    交互式: select Sname,Sage from Student Where Sname=’张三';

    嵌入式(此文宿主语言为C): exec sql select Sname,Sage into :vSname.:vSage from Student where Sname="张三";

    exec sql:引导SQL语句,提供给C编译器,以便对SQl语句预编译成C编译器可识别的语句

    into子句: 用于指出接收SQL语句检索结果的程序比那里

    高级语言–>嵌入式SQL–>DBMSDB

    宿主语言如何与数据库连接

    在嵌入式SQl程序执行之前,首先要与数据库进行连接

    连接:exec sql connect to target-server as connect-name user user-name ; or exec sql connect to default;

    在嵌入式SQL程序执行之后,需要和数据库断开连接

    断开连接:exec sql disconnect connect-name; or exec sql disconnect current;

    如何将宿主语言的变量传递给SQL语句

    变量声明:

    exec sql begin declare section;

    char vSname[10],specName[10]="张三"

    int vSage;

    exec sql end declare section;

    变量使用:变量可传递给SQL语句的where等字句,以便SQL语言能够按照指定的要求进行检索

    exec sql select Sname,Sage into :vSname.:vSage from Student where Sname=:specName;

    SQL语句如何执行

    SQL语句在执行过程中,必须有提交和撤销语句才能确认其操作结果

    提交: exec sql commit work

    撤销: exec sql rollback work

    事务

    定义:事务是一个存取或改变数据库内容的程序的一次执行,或者说一条或多条SQL语句的一次执行被看做一个事务,一般由应用程序员提出,有开始和结束,结束前需要提交或撤销

    事务的特性:

    原子性Atoomicity:DBMS能够保证事务的一组更新操作是原子不可分的,要么全做,要么全不做

    一致性Consistency: DBMS保证事务的操作状态是正确的

    隔离性Isolation:DBMS保证并发的多个事务之间相互不受影响

    持久性Durability:DBMS保证已提交事务的影响是持久的,被撤销事务的影响是可恢复的

    如何将SQL检索到的结构传递回宿主程序进行处理

    单行结果处理

    检索单行结果,可以讲结果直接传送到宿主程序的变量中

    exec sql select [ALL|DISTINCT] expression [,expression...]

    INTO host-variable,[host-variable,...]

    From tableref [corr_name][,tableref[corr_name]...]

    Where search_condition;

    eg:exec sql select Sname,Sage into :vSname.:vSage from Student where Sname=:specName;

    多行结果处理

    游标(Cursor)

    游标是指向某检索记录集的指针,通过这个指针的移动,每次读一行,处理一行,再读一行,直到处理完毕

    读一行的操作是通过Fetch..into实现的,每一次Fetch,都是先向下移动指针,然后再读取,记录集有结束表示EOF,用来标记后面已经没有记录了

    游标的使用需要先定义,再打开,接着一条一条处理,最后关闭

    Cursor的定义:

    EXEC SQL DECLARE cursor_name CURSOR FOR

    Subquery

    [ORDER BY result_column [ASC|DESC][,result_column...]]

    [FOR [READ ONLY |UPDATE [OF columnname[,columnname....]]]]

    eg:

    exec sql declare cur_student cursor for

    select Sno ,Sname,Sclass from Student where Sclass=:vClass

    order by Sno

    for read only;

    Cursor的打开和关闭

    打开: exec sql open cursor_name;

    关闭: exec sql close cursor_name;

    Cursor的数据读取

    exec sql fetch cursor_name

    into host-variable,[host-variable,...]

    eg:exec sql fetch cur_student into :vSno,:vSname,:vsAGE

    数据库的删除与更新

    删除

    查找删除:exec sql delete from tablename [corr_name] where search_condition

    eg:exec sql delete from customers c where c.city='Harbin' and not exists (select * from orders o where o.cid=c.cid)

    定位删除:exec sql delete form tablename [corr_name] where current of cursor_name

    eg:

    exec sql declare delcust cursor for

    select cid from customers c where c.city='harbin' and not exists(select * from orders o where o.cid=c.cid)

    for update of cid;

    exec sql open delcust

    while(TRUE){

    exec sql fetch delcust into :cust_id;

    exec sql delete from customers where current of delcust;

    }

    更新

    查找删除:exec sql update tablename [corr_name] SET columname= expr [,columname=expr...] where search_condition

    eg:exec sql update student s set sclass='035102' where s.sclass=''034101

    定位删除:exec sql update tablename [corr_name] SET columname= expr [,columname=expr...] where current of cursor_name

    eg:

    exec sql declare stud cursor for

    select * from student s where s.class='034101'

    for update of sclass;

    exec sql open stud

    while(TRUE){

    exec sql fetch stud into :vSno,:vSname,:vSclass;

    exec sql update student set sclass='035102' where current of stud;

    }

    插入

    插入:exec sql insert into tablename [(columnname[,columnname,...])] [values (expr[,expr,...])|subqurey]

    eg:exec sql into student (sno,sname,sclass) values('03510128','张三',‘035101’)

    宿主程序如何知道SQL语句的执行状态,是否发生错误

    状态:是指嵌入式SQL语句的执行状态,尤其指一些出错状态,有时程序需要知道这些状态并对这些状态进行处理

    状态捕获及处理由三部分构成

    设置SQL通信区:exec sql include sqlca ,其中SQLCA是一个已被声明过的具有C语言的结构形式的内存信息区,其中的成员变量用来记录SQL语句的执行状态,便于宿主程序读取与处理

    设置状态捕获语句:可设置多次,exec sql whenever condition action;该语句会对气候所有由exec sql语句所引起的对数据库系统的调用自动检查它是否满足条件,condition包括 sqlerror;not found;sqlwarning ,action包括continue;goto;stop;do|call,状态捕获语句Whenever的作用范围是其后的所有exec sql 语句,直到程序中出现另一条相同条件的whenever为止

    状态处理语句:某一段程序以应对SQL操作的某种状态report_error:exec sqlroollback;

    动态SQL,依据条件动态构造SQL语句,但欲访问的表名和字段对编程者是已知的

    静态SQL:SQL语句在程序中已经按要求写好,只需要把一些参数通过变量传送给嵌入式SQL语句即可

    eg:

    SpecName='张三';

    exec sql select Sno,Sname,Sclass into :vSno,:vSname,:vSclass from Student where Sname=:SpecName;

    动态SQL:SQL语言可以在程序中动态构造,形成一个字符串,然后再交给DBMS执行,交给DBMS执行时仍然可以传递变量

    #include

    exec sql include sqlca;

    exec sql begin declare section;

    char user_name="Scott"; char user_pwd[]="tiger";

    char sqltext[]="delete from customers where cid=\'c006\'";

    exec sql end declare section;

    int main()

    {

    exec sql whenever sqlerror goto report_error;

    exec sql connect :user_name identified by :user_pwd;

    exec sql execute immediate :sqltext;

    exec sql commit release: return 0;

    report_error:print_dberror(); exec sql rollback release :return 1;

    }

    动态SQL的两种执行方式:

    1. 立即执行语句(构造的字符串SQL内部没有变量参数):运行时编译并执行 exec sql execute immediate:host-variable;

    2. Prepare-Execute-Using语句(构造的字符串内部有变量参数):Prepare语句先编译,编译后的SQL语句允许动态参数,Execute语句执行,用using语句将动态参数传送给编译好的Sql语句

    exec sql prepare sql_temp from :host-variable;

    -----

    exec sql execute sql_temp using :cond-variable;

    数据字典(Data dictionary)

    定义:是系统维护的一些表或视图的集合,存储了数据库中各类对象的定义醒醒,这些信息又称数据库的元数据–关于数据的数据

    内容:与关系相关的信息;用户与账户信息;统计与描述性数据;物理文件组织信息;索引相关信息

    ODBC(open DataBase Connection)

    定义:ODBC是一种标准—不同语言的应用程序与不同数据库服务器之间通讯的标准

    实现:是一组API,应用程序通过调用ODBC API ,可以实现与数据服务器的连接,向数据库服务器发送SQL命令,一条一条的提取数据库检索结果中的元组传送给应用程序的变量,具体的DBMS提供一套驱动程序,即Driver库函数,供ODBC调用,以便实现数据库与应用系统的连接。

    应用程序与数据库连接:

    ODBC应用前,需要确认具体的DBMS Driver b被安装到ODBC环境中,当应用程序调用ODBC API时,ODBC API会调用具体DBMS Driver 库函数 ,DBMS Driver 库函数则与数据库服务器通讯,执行相应的请求动作并返回检索结果

    ODBC 首先要分配一个SQL环境,再产生一个数据库连接句柄 connection handle

    应用程序使用SQLConnect(),打开一个数据库连接

    使用SQLExecDirect()向数据库发送SQL命令

    使用SQLFetch()获取产生的结果元组

    使用SQLBindCol()绑定C语言变量与结果中的属性

    JDBC(Java DataBase Connetion)

    JDBC是一组Java版的应用程序接口API,提供了Java应用程序与数据库服务器的连接与通讯能力

    更多相关内容
  • 嵌入式sql语言实验报告
  • 嵌入式SQL.doc

    2018-03-21 19:28:22
    SQL是一种双重式语言,它...所以,嵌入式SQL语言就是将SQL语句直接嵌入到程序的源代码中,与其他程序设计语言语句混合。专用的SQL预编译程序将嵌入的SQL语句转换为能被程序设计语言(如C语言)的编译器识别的函数调用。
  • 嵌入式SQL语言

    2022-01-17 09:05:24
    嵌入式SQL语言一、概述二、变量声明与数据库连接1、变量的声明与使用(1) 数据库与DBMS连接(2) 与数据库断开连接(3) SQL执行的提交与撤消(4) 事务的概念与特性三、数据集与游标1、**检索单行结果**2、检索多行结果3、...

    一、概述

    高级语言+SQL语言
    既继承高级语言的过程控制性又结合SQL语言的复杂结果集操作的非过程性;同时又为数据库操作者提供安全可靠的操作方式,通过应用程序进行操作。
    嵌入式SQL语言
    将SQL语言嵌入到某一种高级语言中使用,如C/C++, Java, PowerBuilder等,又称宿主语言(HostLanguage)。

    示例交互式SQL语言
    select Sname, Sage from Student where Sname =‘张三’;

    示例嵌入式SQL语言
    以宿主语言C语言为例
    exec sql select Sname, Sage into :vSname, :vSage from Student where Sname=‘张三’;

    典型特点

    1. exec sql 引导SQL语句:提供给C编译器,以便对SQL语句预编译成C编译器可识别的语句。
    2. 增加 into子句:该子句用于指出接收SQL语句检索结果的程序变量,由冒号引导的程序变量,如:‘:vSname’, ‘:vSage’

    二、变量声明与数据库连接

    1、变量的声明与使用

    在嵌入式SQL语句中可以出现宿主语言语句所使用的变量:
    exec sql select Sname, Sage into :vSname, :vSage from Student where Sname= :specName;

    变量声明:
    exec sql begin declare section; char vSname[10], specName[10]=“张三”; int vSage; exec sql end declare section;

    变量声明和赋值中,要注意:

    1. 宿主程序的字符串变量长度应比字符型字段的长度多1个。因宿主程序的字符串尾部多一个终止符为\0 ‘,而程序中用双引号来描述。
    2. 宿主程序变量类型与数据库字段类型之间有些是有差异的,有些DBMS可支持自动转换,有些不能。

    声明的变量,可以在宿主程序中赋值,然后传递给SQL语句的where等子句中,以使SQL语句能够按照指定的要求(可变化的)进行检索。
    exec sql begin declare section; char vSname[10], specName[10]=“张三”;int vSage; exec sql end declare section;
    exec sql select Sname,Sage into :vSname, :vSage from Student where Sname = :specName ;

    相应的交互式SQL语句:
    select Sname, Sage from Student where Sname =张三’;

    嵌入式比交互式SQL语句灵活了一些:只需改一下变量值,SQL语句便可反复使用,以检索出不同结果。

    (1) 数据库与DBMS连接

    SQL标准连接语法为:
    exec sql connect to target-server as connect-name user user-name;

    exec sql connect to default;
    Oracle中数据库连接:
    exec sql connect :user_name identified by :user_pwd;
    DB2 UDB中数据库连接:
    exec sql connect to mydb user :user_name using :user_pwd;

    (2) 与数据库断开连接

    SQL断开连接的语法
    exec sql disconnect connect-name;

    exec sql disconnect current;
    Oracle中断开连接:
    exec sql commit release;

    exec sql rollback release;
    DB2 UDB中断开连接:
    exec sql connect reset; exec sql disconnect current;

    (3) SQL执行的提交与撤消

    SQL语句在执行过程中,必须有提交和撤消语句才能确认其操作结果

    SQL执行的提交:
    exec sql commit work;
    SQL执行的撤消:
    exec sql rollback work;

    很多DBMS都设计了捆绑提交/撤消与断开连接在一起的语句,以保证在断开连接之前使用户确认提交或撤消先前的工作
    例如Oracle中:
    exec sql commit release;

    exec sql rollback release;

    (4) 事务的概念与特性

    事务:(从应用程序员角度)是一个存取或改变数据库内容的程序的一次执行或者说一条或多条SQL语句的一次执行被看作一个事务

    事务一般是由应用程序员提出,因此有开始和结束,结束前需要提交或撤消。

    Begin Transaction
    exec sql …
    exec sql …
    exec sql commit work | exec sql rollback workEnd Transaction

    在嵌入式SQL程序中,任何一条数据库操纵语句(如exec sql select等)都会引发一个新事务的开始,只要该程序当前没有正在处理的事务。而事务的结束是需要应用程序员通过commit或rollback确认的。因此Begin Transaction和End Transaction两行语句是不需要的。

    事务∶(从微观角度,或者从DBMS角度)是数据库管理系统提供的控制数据操作的一种手段,通过这一手段,应用程序员将一系列的数据库操作组合在一起作为一个整体进行操作和控制,以便数据库管理系统能够提供一致性状态转换的保证。
    在这里插入图片描述
    事务的特性: ACID

    1. 原子性Atomicity : DBMS能够保证事务的一组更新操作是原子不可分的,即对DB而言,要么全做,要么全不做
    2. 一致性Consistency: DBMS保证事务的操作状态是正确的,符合一致性的操作规则,它是进一步由隔离性来保证的
    3. 隔离性lsolation: DBMS保证并发执行的多个事务之间互相不受影响。例如两个事务T1和T2,即使并发执行,也相当于或者先执行了T1,再执行T2;或者先执行了T2,再执行T1。
    4. 持久性Durability: DBMS保证已提交事务的影响是持久的,被撤销事务的影响是可恢复的。

    换句话说:具有ACID特性的若干数据库基本操作的组合体被称为事务。

    事务处理是DBMS的核心技术。

    在这里插入图片描述
    在这里插入图片描述
    步骤:

    1. 引入SQLCA
    2. 声明变量
    3. 设置SQL错误捕获语句
    4. 连接数据库
    5. 设置SQL语句,并提交
    6. 断开连接

    三、数据集与游标

    1、检索单行结果

    可将结果直接传送到宿主程序的变量中

    EXEC SQL SELECT[ALL | DISTINCT]expression [, expression…]
    INTO host-variable , [host-variable,…]
    FROM tableref [corr_name] [ , tableref [corr_name] …]WHEREsearch_condition;

    示例
    exec sql select Sname, Sage into :vSname,:vSage from Student where Sname = :specName ;

    2、检索多行结果

    检索多行结果,则需使用游标(Cursor)
    游标是指向某检索记录集的指针。通过这个指针的移动,每次读一行,处理一行,再读一行….,直至处理完毕。

    读一行操作是通过Fetch…into语句实现的:每一次Fetch,都是先向下移动指针,然后再读取。
    记录集有结束标识EOF,用来标记后面已没有记录了

    3、游标(Cursor)的使用

    游标(Cursor)的使用需要先定义、再打开(执行)、接着一条接一条处理,最后再关闭

    exec sql declare cur_student cursor for
    select Sno, Sname,Sclass from Student where Sclass=035101’;
    exec sql open cur_student;
    exec sql fetch cur_student into :vSno, :vSname, :vSclass;
    exec sql close cur_student;

    游标可以定义一次,多次打开(多次执行),多次关闭

    Cursor的定义:declare cursor

    EXEC sQL DECLAREcursor_name CURSOR FOR
    Subquery
    [ORDER BY result_column [ASC | DESC][, result_column …]
    [FOR [ READ ONLY | UPDATE [OF columnname [, columnname…]]l];

    示例
    exec sql declare cur_student cursor for select Sno, Sname, Sclass from Student where Sclass= :vClass order by Sno for read only ;

    Cursor的打开和关闭open cursor //close cursor
    EXEC SQL OPEN cursor_name;
    EXEC SQL CLOSE cursor_name;

    Cursor的数据读取Fetch
    EXEC SQL FETCH cursor_name INTOhost-variable , [host-variable,...];

    示例
    exec sql declare cur_student cursor for select Sno, Sname, Sclass from Student where Sclass= :vClass order by Sno for read only ;
    exec sql open cur_student;

    exec sql fetch cur_student into :vSno, :vSname, :vSage…
    exec sql close cur_student;

    四、可滚动游标及数据库的增删改

    1、可滚动游标的概念、定义和使用

    标准的游标始终是自开始向结束方向移动的,每fetch一次,向结束方向移动一次;一条记录只能被访问一次;再次访问该记录只能关闭游标后重新打开。
    可滚动游标是可使游标指针在记录集之间灵活移动、使每条记录可以反复被访问的一种游标。

    EXEC SQL DECLAREcursor_name [INSENSITIVE] [SCROLL] CURSOR
    [WITH HOLD] FOR Subquery
    [ORDER BY result_column [ASC | DESC][, result_column …][FOR READ ONLY | FOR UPDATE OF columnname [,
    columnname ]…];
    EXEC SQL FETCH
    [NEXT |PRIOR | FIRST | LAST
    I [ABSOLUTE | RELATIVE] value_spec ]
    FROM cursor_name INTO host-variable [, host-variable …];

    NEXT向结束方向移动一条;
    PRIOR向开始方向移动一条;
    FIRST回到第一条;
    LAST移动到最后一条;
    ABSOLUT value_spec定向检索指定位置的行,
    value_spec由1至当前记录集最大值;
    RELATIVE value_spec相对当前记录向前或向后移动,
    value_spec为正数向结束方向移动,为负数向开始方向移动

    可滚动游标移动时需判断是否到结束位置,或到起始位置。可通过判断是否到EOF位置(最后一条记录的后面),或BOF位置(起始记录的前面)。如果不需区分,可通过whenever not found语句设置来检测。

    2、数据的删除与更新

    一种是查找删除(与交互式DELETE语句相同),一种是定位删除
    EXEC sQL DELETE FROM tablename [corr_name]
    WHERE search_condition | WHERE CURRENT OF cursor_name;

    示例:查找删除
    exec sql delete from customers c where c.city =‘Harbin' and not exists ( select * from orders o where o.cid = c.cid);

    示例:定位删除
    exec sql declare delcust cursor for
    select cid from customers c where c.city =‘harbin' and not exists ( select * from orders o where o.cid = c.cid)for update of cid;
    exec sql open delcustWhile (TRUE){
    exec sql fetch delcust into :cust_id;
    exec sql delete from customers where current of delcust ; }

    3、数据库记录的更新

    一种是查找更新(与交互式Update语句相同),一种是定位更新
    EXEC sQL UPDATEtablename [corr_name]
    SET columnname = expr [, columnname = expr …]
    [ WHEREsearch_condition ] | WHERE CURRENT OF cursor_name;

    示例:查找更新
    execsql update student s set sclass ='035102’ where s.sclass = ‘034101’

    示例:定位更新
    exec sql declare stud cursor for
    select * from student s where s.sclass =‘034101’for update of sclass;
    exec sql open stud

    While (TRUE){
    exec sql fetch stud into :vSno, :vSname, :vSclass;
    exec sql update student set sclass = '035102’where current ofstud ; }

    4、数据库记录的插入

    只有一种类型的插入语句
    EXEC SQL INSERT INTOtablename [(columnname [,columnname, …] )]
    [ VALUES (expr [ , expr , …] ) | subqurey ];

    示例:插入语句
    exec sql insert into student ( sno, sname, sclass) values ('03510128',‘张三',‘035101');

    示例:插入语句
    exec sql insert into masterstudent ( sno, sname,sclass)
    select sno, sname, sclass from student;

    5、示例:宿主语言与SQL结合的过程性控制

    求数据库中某一列位于中值的那一行

    #include <stdio.h>
    #include "prompt.h”
    exec sql include sqlca;
    char custprompt[ ] ="Please enter a customer ID:int main()
    {
    exec sql begin declare section;
    char cid[5],user_name[20], user_pwd[10];
    double dollars; 
    int ocount;
    exec sql end declare section;
    exec sql declare dollars_cursor cursor for
    select dollars from orders where cid = :cid and dollars is not nullorder by dollars;
    
    int i;
    exec sql whenever sqlerror goto report_error;
    strcpy(user_name, "poneilsql");
    strcpy(user_pwd, "xxXx”);
    exec sql connect :user_name identified by :user_pwd;
    While ( prompt(custprompt, 1, cid ,4)>=0 {
    exec sql select count(dollars) into :ocount from orders where cid =:cid ;
    if (ocount ==0 )
    printf("No record reviewed for cid value %sln", cid);
    continue; }
    exec sql open dollars _cursor;
    for (i =0; i< (ocount+1)/2; i++)
    exec sql fetch dollars_cursor into :dollars;
    exec sql close dollars_cursor;
    exec sql commit work;
    printf("Median dollar amount =%fln”, dollars); }
    }
    

    五、状态捕获及错误处理机制

    状态捕获及其处理
    状态,是嵌入式SQL语句的执行状态,尤其指一些出错状态;有时程序需要知道这些状态并对这些状态进行处理

    嵌入式SQL程序中,状态捕获及处理有三部分构成

    1. 设置SQL通信区:一般在嵌入式SQL程序的开始处便设置。
      exec sql include sqlca;
    2. 设置状态捕获语句:在嵌入式SQL程序的任何位置都可设置;可多次设置;但有作用域。
      exec sql whenever sqlerror goto report_error;
    3. 状态处理语句:某一段程序以应对SQL操作的某种状态
      report_error: exec sql rollback;

    SQL通信区:SQLCA
    SQLCA是一个已被声明过的具C语言的结构形式的内存信息区,其中的成员变量用来记录SQL语句执行的状态,便于宿主程序读取与处理
    SQLCA是DBMS(执行SQL语句)与宿主程序之间交流的桥梁之一

    状态捕获语句
    exec sql whenever condition action;

    Whenever语句的作用是设置一个“条件陷阱”,该条语句会对其后面的所有由Exec SQL语句所引起的对数据库系统的调用自动检查它是否满足条件(由condition指出).

    1. SQLERROR:检测是否有SQL语句出错。其具体意义依赖于特定的
    2. DBMSONOT FOUND:执行某一SQL语句后,没有相应的结果记录出现
    3. SQLWARNING:不是错误,但应引起注意的条件

    如果满足condition,则要采取一些动作(由action指出)

    1. CONTINUE:忽略条件或错误,继续执行
    2. GOTO标号:转移到标号所指示的语句,去进行相应的处理STOP:终止程序运行、撤消当前的工作、断开数据库的连接
    3. DO函数或CALL函数:调用宿主程序的函数进行处理,函数返回后从引发该condition的Exec SQL语句之后的语句继续进行。

    状态捕获语句Whenever的作用范围是其后的所有Exec SQL语句,一直到程序中出现另一条相同条件的Whenever语句为止,后面的将覆盖前面的。

    int main(){
    exec sql whenever sqlerror goto handle_error;
    exec sql create table customers(cid char(4) not null,
    cname varchar(13), ... ...);
    handle_error:
    exec sql whenever sqlerror continue;
    //控制是否无限循环:无,则可能:有,则不会
    exec sql drop customers;exec sql disconnect;
    fprintf(stderr,"could not create customers tableln");return -1;
    }
    

    典型DBMS系统记录状态信息的三种方法状态记录

    1. sqlcode:典型DBMS都提供一个sqlcode变量来记录其执行sql语句的状态,但不同DBMS定义的sqlcode值所代表的状态意义可能是不同的,需要查阅相关的DBMS资料来获取其含义
    2. sqlcode== 0, successful call;
    3. sqIcode<0, error, e.g., from connect, database does not exist , -16;
    4. sqlcode > 0, warning, e.g., no rows retrieved from fetch
    5. sqlca.sqlcode:支持SQLCA的产品一般要在SQLCA中填写sqlcode来记录上述信息;除此而外,sqlca还有其他状态信息的记录
    6. sqlstate:有些DBMS提供的记录状态信息的变量是sqlstate或sqlca.sqlstate

    当我们不需明确知道错误类型,而只需知道发生错误与否,则我们只要使用前述的状态捕获语句即可,而无需关心状态记录变量(隐式状态处理)
    但我们程序中如要自行处理不同状态信息时,则需要知道以上信息,但也需知道正确的操作方法(显式状态处理)

    显式状态处理示例

    exec sql begin declar section;
    char sQLSTATE[6];
    exec sql end declare section;

    exec sql whenever sqlerror goto handle_error;

    exec sql whenever sqlerror continue;exec sql create table custs
    (cid char(4) not null, cname varchar(13),... .…. );

    if (strcmp(SQLSTATE, "82100")==0)
    <处理82100错误的程序>

    展开全文
  • 为什么要引入嵌入式SQL SQL语言是非过程性语言 事务处理应用需要高级语言 这两种方式细节上有差别,在程序设计的环境下,SQL语句要做某些必要的扩充 嵌入式SQL的处理过程 主语言 嵌入式SQL是将SQL语句嵌入程序设计...

    SQL语言提供了两种不同的使用方式
    交互式
    嵌入式
    为什么要引入嵌入式SQL
    SQL语言是非过程性语言
    事务处理应用需要高级语言
    这两种方式细节上有差别,在程序设计的环境下,SQL语句要做某些必要的扩充

    嵌入式SQL的处理过程

    主语言

    嵌入式SQL是将SQL语句嵌入程序设计语言中,被嵌入的程序设计语言,如C、C++、Java,称为宿主语言,简称主语言。

    处理过程

    预编译方法
    在这里插入图片描述

    为了区分SQL语句与主语言语句,所有SQL语句必须加前缀EXEC SQL,主语言为C语言时,语句格式:

    EXEC SQL <SQL语句>;
    

    嵌入式SQL语句与主语言之间的通信

    将SQL嵌入到高级语言中混合编程,程序中会含有两种不同计算模型的语句

    SQL语句
    描述性的面向集合的语句
    负责操纵数据库
    高级语言语句
    过程性的面向记录的语句
    负责控制逻辑流程
    它们之间应该如何通信?

    数据库工作单元与源程序工作单元之间的通信

    (1)向主语言传递SQL语句的执行状态信息,使主语言能够据此控制程序流程,主要用SQL通信区实现
    (2)主语言向SQL语句提供参数,主要用主变量实现
    (3)将SQL语句查询数据库的结果交主语言处理,主要用主变量和游标实现

    SQL通信区

    SQLCA: SQL Communication Area
    SQLCA是一个数据结构
    SQLCA的用途
    SQL语句执行后,系统反馈给应用程序信息
    描述系统当前工作状态
    描述运行环境
    这些信息将送到SQL通信区中
    应用程序从SQL通信区中取出这些状态信息,据此决定接下来执行的语句
    SQLCA使用方法
    定义SQLCA
    用EXEC SQL INCLUDE SQLCA定义
    使用SQLCA
    SQLCA中有一个存放每次执行SQL语句后返回代码的变量SQLCODE
    如果SQLCODE等于预定义的常量SUCCESS,则表示SQL语句成功,否则表示出错
    应用程序每执行完一条SQL 语句之后都应该测试一下SQLCODE的值,以了解该SQL语句执行情况并做相应处理

    主变量

    主变量
    嵌入式SQL语句中可以使用主语言的程序变量来输入或输出数据
    在SQL语句中使用的主语言程序变量简称为主变量(Host Variable)
    主变量的类型
    输入主变量
    由应用程序对其赋值,SQL语句引用
    输出主变量
    由SQL语句对其赋值或设置状态信息,返回给应用程序
    指示变量
    是一个整型变量,用来“指示”所指主变量的值或条件
    一个主变量可以附带一个指示变量(Indicator Variable)
    指示变量的用途
    指示输入主变量是否为空值
    检测输出变量是否为空值,值是否被截断
    在SQL语句中使用主变量和指示变量的方法
    说明主变量和指示变量

    BEGIN DECLARE SECTION
    	...
    	...  		(说明主变量和指示变量)
    	...
    END DECLARE SECTION
    

    使用主变量
    说明之后的主变量可以在SQL语句中任何一个能够使用表达式的地方出现
    为了与数据库对象名(表名、视图名、列名等)区别,SQL语句中的主变量名前要加冒号(:)作为标志
    使用指示变量
    指示变量前也必须加冒号标志
    必须紧跟在所指主变量之后
    在SQL语句之外(主语言语句中)使用主变量和指示变量的方法
    可以直接引用,不必加冒号

    游标

    为什么要使用游标
    SQL语言与主语言具有不同数据处理方式
    SQL语言是面向集合的,一条SQL语句原则上可以产生或处理多条记录
    主语言是面向记录的,一组主变量一次只能存放一条记录
    仅使用主变量并不能完全满足SQL语句向应用程序输出数据的要求
    嵌入式SQL引入了游标的概念,用来协调这两种不同的处理方式
    游标
    游标是系统为用户开设的一个数据缓冲区,存放SQL语句的执行结果
    每个游标区都有一个名字
    用户可以用SQL语句逐一从游标中获取记录,并赋给主变量,交由主语言进一步处理

    建立和关闭数据库连接

    (1)建立数据库连接

    EXEC SQL CONNECT TO target[AS connection-name][USER user-name]; 
    

    target是要连接的数据库服务器
    常见的服务器标识串,如@:
    包含服务器标识的SQL串常量
    DEFAULT
    connect-name是可选的连接名,连接名必须是一个有效的标识符
    在整个程序内只有一个连接时可以不指定连接名
    程序运行过程中可以修改当前连接

    EXEC SQL SET CONNECTION connection-name
       |DEFAULT;
    

    (2)关闭数据库连接

    EXEC SQL DISCONNECT [connection];
    

    程序实例

    [例8.1] 依次检查某个系的学生记录,交互式更新某些学生年龄。

    EXEC SQL BEGIN DECLARE SECTION;    /*主变量说明开始*/ 
    	char Deptname[20];
    	char Hsno[9];
    	char Hsname[20]; 
    	char Hssex[2];
    	int HSage;
    	int NEWAGE;
    EXEC SQL END DECLARE SECTION;       /*主变量说明结束*/
    long SQLCODE;
    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 TEST@localhost:54321 USER
                               "SYSTEM"/"MANAGER";         /*连接数据库TEST*/
    	EXEC SQL DECLARE SX CURSOR FOR      /*定义游标SX*/
    		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;                         /*断开数据库连接*/
    }
    

    不用游标的SQL语句

    不用游标的SQL语句的种类

    说明性语句
    数据定义语句
    数据控制语句
    查询结果为单记录的SELECT语句
    非CURRENT形式的增删改语句

    查询结果为单记录的SELECT语句

    这类语句不需要使用游标,只需用INTO子句指定存放查询结果的主变量。
    [例8.2] 根据学生号码查询学生信息。

    EXEC SQL SELECT Sno,Sname,Ssex,Sage,Sdept  
     	    INTO:Hsno,:Hname,:Hsex,:Hage,:Hdept
               FROM  Student
     	    WHERE Sno=:givensno;
     /*把要查询的学生的学号赋给为了主变量givensno*/
    

    INTO子句、WHERE子句和HAVING短语的条件表达式中均可以使用主变量
    查询返回的记录中,可能某些列为空值NULL
    如果查询结果实际上并不是单条记录,而是多条记录,则程序出错,关系数据库管理系统会在SQLCA中返回错误信息
    [例8.3] 查询某个学生选修某门课程的成绩。假设已经把将要查询的学生的学号赋给了主变量givensno,将课程号赋给了主变量givencno。

    EXEC SQL SELECT Sno,Cno,Grade
     	   INTO :Hsno,:Hcno,:Hgrade:Gradeid  
    						/*指示变量Gradeid*/
              FROM  SC
     	   WHERE Sno=:givensno AND Cno=:givencno;
    

    如果Gradeid < 0,不论Hgrade为何值,均认为该学生成绩为空值。

    非CURRENT形式的增删改语句

    在UPDATE的SET子句和WHERE子句中可以使用主变量,SET子句还可以使用指示变量
    [例8.4] 修改某个学生选修1号课程的成绩。

    EXEC SQL UPDATE SC
               SET Grade=:newgrade
                                                	/*修改的成绩已赋给主变量:newgrade*/
               WHERE Sno=:givensno;
    				/*学号赋给主变量:givensno*/
    

    [例8.5] 某个学生新选修了某门课程,将有关记录插入SC表中。假设插入的学号已赋给主变量

    stdno,课程号已赋给主变量couno。
    	gradeid=-1/*gradeid为指示变量,赋为负值*/
    	EXEC SQL INSERT
                    INTO SC(Sno,Cno,Grade)
                    VALUES(:stdno,:couno,:gr :gradeid)/*:stdno,:couno,:gr为主变量*/
    

    由于该学生刚选修课程,成绩应为空,所以要把指示变量赋为负值

    使用游标的SQL语句

    必须使用游标的SQL语句

    查询结果为多条记录的SELECT语句
    CURRENT形式的UPDATE语句
    CURRENT形式的DELETE语句

    查询结果为多条记录的SELECT语句

    使用游标的步骤
    (1)说明游标
    (2)打开游标
    (3)推进游标指针并取当前记录
    (4)关闭游标

    说明游标

    使用DECLARE语句
    语句格式

    EXEC SQL DECLARE <游标名> CURSOR
                         FOR <SELECT语句>;
    

    功能
    是一条说明性语句,这时关系数据库管理系统并不执行SELECT语句

    打开游标

    使用OPEN语句
    语句格式

      EXEC SQL OPEN <游标名>;
    

    功能
    打开游标实际上是执行相应的SELECT语句,把查询结果取到缓冲区中
    这时游标处于活动状态,指针指向查询结果集中的第一条记录

    推进游标指针并取当前记录

    使用FETCH语句
    语句格式

    EXEC SQL FETCH <游标名> 
         INTO <主变量>[<指示变量>]
    	  [,<主变量>[<指示变量>]]...;
    

    功能
    指定方向推动游标指针,同时将缓冲区中的当前记录取出来送至主变量供主语言进一步处理

    关闭游标

    使用CLOSE语句
    语句格式

      EXEC SQL CLOSE <游标名>;
    

    功能
    关闭游标,释放结果集占用的缓冲区及其他资源
    说明
    游标被关闭后,就不再和原来的查询结果集相联系
    被关闭的游标可以再次被打开,与新的查询结果相联系

    CURRENT形式的UPDATE语句和DELETE语句

    CURRENT形式的UPDATE语句和DELETE语句的用途
    非CURRENT形式的UPDATE语句和DELETE语句
    面向集合的操作
    一次修改或删除所有满足条件的记录
    如果只想修改或删除其中某个记录
    用带游标的SELECT语句查出所有满足条件的记录
    从中进一步找出要修改或删除的记录
    用CURRENT形式的UPDATE语句和DELETE语句修改或删除之
    UPDATE语句和DELETE语句中要用子句
    WHERE CURRENT OF <游标名>
    表示修改或删除的是最近一次取出的记录,即游标指针指向的记录
    不能使用CURRENT形式的UPDATE语句和DELETE语句
    当游标定义中的SELECT语句带有UNION或ORDER BY子句
    该SELECT语句相当于定义了一个不可更新的视图

    动态SQL

    静态嵌入式SQL

    静态嵌入式SQL语句能够满足一般要求
    无法满足要到执行时才能够确定要提交的SQL语句、查询的条件

    动态嵌入式SQL

    允许在程序运行过程中临时“组装”SQL语句
    支持动态组装SQL语句和动态参数两种形式

    使用SQL语句主变量

    SQL语句主变量
    程序主变量包含的内容是SQL语句的内容,而不是原来保存数据的输入或输出变量
    SQL语句主变量在程序执行期间可以设定不同的SQL语句,然后立即执行
    [例8.6] 创建基本表TEST。

    EXEC SQL BEGIN DECLARE SECTION;
    		   const char *stmt="CREATE TABLE test(a int);";  
               /*SQL语句主变量,内容是创建表的SQL语句*/
    EXEC SQL END DECLARE SECTION;
    	... 
    EXEC SQL EXECUTE IMMEDIATE :stmt;		
               /*执行动态SQL语句*/
    

    动态参数

    动态参数
    SQL语句中的可变元素
    使用参数符号(?)表示该位置的数据在运行时设定
    和主变量的区别
    动态参数的输入不是编译时完成绑定
    而是通过 PREPARE语句准备主变量和执行语句EXECUTE绑定数据或主变量来完成
    使用动态参数的步骤
    (1)声明SQL语句主变量
    (2)准备SQL语句(PREPARE)

    EXEC SQL PREPARE <语句名> 
    	   FROM <SQL语句主变量>;
    

    执行准备好的语句(EXECUTE)

    EXEC SQL EXECUTE <语句名> 
    		     [INTO <主变量表>]            
                  [USING <主变量或常量>];
    

    [例8.7] 向TEST中插入元组。

    EXEC SQL BEGIN DECLARE SECTION;
    	const char *stmt = "INSERT INTO test VALUES(?);";
                                        /*声明SQL主变量内容是INSERT语句 */
    EXEC SQL END DECLARE SECTION;
    ... 
    EXEC SQL PREPARE mystmt FROM :stmt; /*准备语句*/
    ... 
    EXEC SQL EXECUTE mystmt USING 100;
                                   /*执行语句,设定INSERT语句插入值100 */
    EXEC SQL EXECUTE mystmt USING 200;  
                                  /* 执行语句,设定INSERT语句插入值200 */
    

    欢迎大家加我微信交流讨论(请备注csdn上添加)
    在这里插入图片描述

    展开全文
  • 文章目录 第十二章 使用嵌入式SQL(一)编译嵌入式SQL嵌入式SQL和宏预处理器在嵌入式SQL中包含文件#SQLCompile宏指令嵌入式SQL语法`&sql`指令&sql替代语法&sql标记语法嵌入式SQL和行偏移量 第十二章 使用嵌入式...

    第十二章 使用嵌入式SQL(一)

    可以将SQL语句嵌入InterSystemsIRIS®数据平台使用的ObjectScript代码中。这些嵌入式SQL语句在运行时转换为优化的可执行代码。

    嵌入式SQL有两种:

    • 一个简单的嵌入式SQL查询只能返回单行中的值。简单嵌入式SQL还可以用于单行插入,更新和删除以及其他SQL操作。
    • 基于游标的嵌入式SQL查询可以遍历查询结果集,并从多行中返回值。基于游标的嵌入式SQL也可以用于多行更新和删除SQL操作。

    注意:嵌入式SQL不能输入到Terminal命令行,也不能在XECUTE语句中指定。要从命令行执行SQL,请使用$SYSTEM.SQL.Execute()方法或SQL Shell接口。

    编译嵌入式SQL

    当包含嵌入式SQL的例程被编译时,嵌入式SQL不会被编译。
    相反,嵌入式SQL的编译发生在SQL代码的第一次执行(运行时)。
    第一次执行定义了一个可执行的缓存查询。
    这与动态SQL的编译类似,在动态SQL中,直到执行SQL Prepare操作才编译SQL代码。

    直到第一次执行例程,嵌入式SQL代码才会根据SQL表和其他实体进行验证。
    因此,可以编译包含嵌入式SQL的持久化类的例程或方法,这些SQL引用在例程编译时不存在的表或其他SQL实体。
    由于这个原因,大多数SQL错误是在运行时执行时返回的,而不是编译时返回的。

    在例程编译时,对嵌入式SQL执行SQL语法检查。
    ObjectScript编译器失败,并为嵌入式SQL中的无效SQL语法生成编译错误。

    可以使用Management Portal SQL接口测试嵌入式SQL中指定的SQL实体是否存在,而不需要执行SQL代码。
    这在验证嵌入式SQL代码中进行了描述,该代码既验证SQL语法,又检查是否存在SQL实体。
    可以选择在运行时执行之前验证嵌入式SQL代码,方法是使用/compileembedded=1限定符编译包含嵌入式SQL代码的例程,如验证嵌入式SQL代码中所述。

    成功执行的嵌入式SQL语句将生成一个缓存的查询。该嵌入式SQL的后续执行将使用缓存的查询,而不是重新编译嵌入式SQL源。这提供了对嵌入式SQL的缓存查询的性能优势。

    当首次使用OPEN命令打开游标时,会执行基于游标的Embedded SQL语句的运行时执行。在执行的这一点上,将生成优化的缓存查询计划,如管理门户中的“ SQL语句”列表中所示。列出的“ SQL语句”位置是包含嵌入式SQL代码的例程的名称。请注意,执行嵌入式SQL不会在“缓存的查询”列表中生成一个条目。这些清单(带有类名称,例如%sqlcq.USER.cls1)是由Dynamic SQL查询创建的。

    注意:较早版本的IRIS中使用的#SQLCompile Mode预处理程序语句已被弃用。它已被解析,但不再对大多数嵌入式SQL命令执行任何操作。无论#SQLCompile Mode设置如何,大多数嵌入式SQL命令都会在运行时进行编译。但是,设置#SQLCompile Mode = deferred对于少量的嵌入式SQL命令仍然有意义,因为它会强制在运行时编译所有类型的嵌入式SQL命令。

    嵌入式SQL和宏预处理器

    可以在方法内和触发器内(前提是它们已定义为使用ObjectScript)或在ObjectScript MAC例程内使用嵌入式SQL。 MAC例程由InterSystems IRIS宏预处理器处理,并转换为INT(中间)代码,随后将其编译为可执行的OBJ代码。这些操作是在包含嵌入式SQL的例程的编译时执行的,而不是在嵌入式SQL代码本身上执行的,嵌入式SQL代码本身直到运行时才进行编译。

    **如果嵌入式SQL语句本身包含InterSystems IRIS宏预处理器语句(#命令,##函数或$$macro引用),则在编译例程时将编译这些语句,并在运行时将其提供给SQL代码。**这可能会影响包含ObjectScript代码主体的CREATE PROCEDURECREATE FUNCTIONCREATE METHODCREATE QUERYCREATE TRIGGER语句。

    在嵌入式SQL中包含文件

    嵌入式SQL语句要求它们引用的任何宏包含文件都必须在运行时加载到系统上。

    因为嵌入式SQL的编译将推迟到首次引用之前进行,所以嵌入式SQL类的编译上下文将是运行时环境,而不是包含类或例程的编译时环境。如果运行时当前名称空间与包含例程的编译时名称空间不同,则编译时名称空间中的包含文件可能在运行时名称空间中不可见。在这种情况下,将发生以下情况:

    1. 如果在运行时名称空间中看不到包含文件,则嵌入式SQL编译将删除所有包含文件。由于SQL编译很少需要包含文件,因此如果没有这些文件,运行时嵌入式SQL编译通常会成功。
    2. 如果删除包含文件后编译失败,则InterSystems IRIS错误将报告例程编译时名称空间,嵌入式SQL运行时名称空间以及从运行时名称空间看不到的包含文件列表。

    #SQLCompile宏指令

    宏预处理器提供了三个与嵌入式SQL一起使用的预处理器指令:

    • #SQLCompile Select指定从Select语句返回时数据显示的格式,或者指定插入或更新语句时数据输入所需的格式,或者指定Select输入主机变量。
      它支持以下6个选项:Logical(默认值)DisplayODBCRuntimeText(与Display相同)FDBMS(见下文)。
      如果#SQLCompile Select=Runtime,可以使用$SYSTEM.SQL.Util.SetOption("SelectMode",n)方法来更改数据的显示方式。
      n取值为0=Logical1=ODBC2=Display

    无论指定了#SQLCompile Select选项,INSERTUPDATE都会自动将指定的数据值转换为相应的逻辑格式进行存储。

    不管指定了#SQLCompile Select选项,Select都会自动将输入的主机变量值转换为谓词匹配的相应逻辑格式。

    使用#SQLCompile Select进行查询显示如下示例所示。
    这些示例显示DOB(出生日期)值,然后将SelectMode更改为ODBC格式,然后再次显示DOB
    在第一个例子中,改变SelectMode对显示没有影响;
    在第二个示例中,因为#SQLCompile Select=Runtime,更改SelectMode将更改显示:

    /// d ##class(PHA.TEST.SQL).EmbedSQL()
    ClassMethod EmbedSQL()
    {
    	#SQLCompile Select=Display
    	&sql(SELECT DOB INTO :a FROM Sample.Person)
    	IF SQLCODE<0 {
    		WRITE "SQLCODE error ",SQLCODE," ",%msg  
    		QUIT
    	} ELSEIF SQLCODE=100 {
    		WRITE "Query returns no results"  
    		QUIT
    	}
    	WRITE "1st date of birth is ",a,!
    	DO $SYSTEM.SQL.Util.SetOption("SelectMode",1)
    	WRITE "changed select mode to: ",$SYSTEM.SQL.Util.GetOption("SelectMode"),!
    	&sql(SELECT DOB INTO :b FROM Sample.Person)
    	WRITE "2nd date of birth is ",b
    }
    
    DHC-APP>d ##class(PHA.TEST.SQL).EmbedSQL()
    1st date of birth is 04/25/1990
    2nd date of birth is 04/25/1990
    
    /// d ##class(PHA.TEST.SQL).EmbedSQL1()
    ClassMethod EmbedSQL1()
    {
       #SQLCompile Select=Runtime
       &sql(SELECT DOB INTO :a FROM Sample.Person)
          IF SQLCODE<0 {WRITE "SQLCODE error ",SQLCODE," ",%msg  QUIT}
          ELSEIF SQLCODE=100 {WRITE "Query returns no results"  QUIT}
       WRITE "1st date of birth is ",a,!
       //DO $SYSTEM.SQL.Util.SetOption("SelectMode",1)
       //WRITE "changed select mode to: ",$SYSTEM.SQL.Util.GetOption("SelectMode"),!
       &sql(SELECT DOB INTO :b FROM Sample.Person)
       WRITE "2nd date of birth is ",b
    }
    
    DHC-APP>d ##class(PHA.TEST.SQL).EmbedSQL1()
    1st date of birth is 1990-04-25
    2nd date of birth is 1990-04-25
    
    • 提供#SQLCompile Select=FDBMS是为了使嵌入式SQL能够以与FDBMS相同的方式格式化数据。
      如果一个查询在WHERE子句中有一个常量值,FDBMS模式假定它是一个显示值,并使用DisplayToLogical转换对它进行转换。
      如果一个查询在WHERE子句中有一个变量,FDBMS模式使用FDBMSToLogical conversion对它进行转换。
      应该设计FDBMS转换方法来处理三种FDBMS变量格式:InternalInternal_$c(1)_External$c(1)_External
      如果查询选择一个变量,它将调用LogicalToFDBMS转换方法。
      这个方法返回Internal_$c(1)_External

    • #SQLCompile Path(或#Import)指定模式搜索路径,用于解析SELECTCALLINSERTUPDATEDELETETRUNCATE表等数据管理命令中未限定的表、视图和存储过程名称。
      如果没有指定模式搜索路径,或者在指定的模式中找不到表,InterSystems IRIS将使用默认模式。
      数据定义语句如ALTER TABLEDROP VIEWCREATE INDEXCREATE TRIGGER会忽略#SQLCompile Path#Import
      数据定义语句使用默认模式来解析非限定名称。

    • #SQLCompile Audit计是一个布尔开关,指定嵌入式SQL语句的执行是否应该记录在系统事件审计日志中。

    嵌入式SQL语法

    &sql指令

    嵌入式SQL语句由&sql()指令与其余代码分开,如以下示例所示:

    /// d ##class(PHA.TEST.SQL).EmbedSQL2()
    ClassMethod EmbedSQL2()
    {
    	NEW SQLCODE,a
    	WRITE "调用嵌入式SQL",!
    	&sql(SELECT Name INTO :a FROM Sample.Person)
    	IF SQLCODE<0 {
    		WRITE "SQLCODE错误 ",SQLCODE," ",%msg  QUIT
    	} ELSEIF SQLCODE=100 {
    		WRITE "查询没有结果"  QUIT
    	}
    	WRITE "名字是 ",a
    }
    
    DHC-APP>d ##class(PHA.TEST.SQL).EmbedSQL2()
    调用嵌入式SQL
    名字是 Adams,Diane F.
    

    使用指定一个或多个主机变量的INTO子句返回结果。在这种情况下,主机变量名为:a

    &sql指令不区分大小写;可以使用&sql&SQL&Sql等。 &sql指令必须后跟一个开放的括号,并且中间没有空格,换行符或注释。 &sql指令可以与标签在同一行上使用,如以下示例所示:

    /// d ##class(PHA.TEST.SQL).EmbedSQL3()
    ClassMethod EmbedSQL3()
    {
    Mylabel  &sql(
    			SELECT Name INTO :a 
    			FROM Sample.Person
    			)
    }
    

    &sql指令的主体应包含一个有效的Embedded SQL语句,并用括号括起来。可以按照自己喜欢的任何方式设置SQL语句的格式:SQL会忽略空格和换行符。 Studio可以识别&sql指令,并使用可识别SQL的着色器对SQL代码语句进行语法着色。

    当宏预处理器遇到&sql指令时,它将随附的SQL语句交给SQL查询处理器。查询处理器返回执行查询所需的代码(ObjectScript INT格式)。然后,宏预处理器用此代码(或对包含该代码的标签的调用)替换&sql指令。在Studio中,可以根据需要查看生成的代码,方法是查看为类或例程生成的INT代码(使用“查看”菜单中的“查看其他代码”选项)。

    如果&sql指令包含无效的Embedded SQL语句,则宏预处理器会生成编译错误。无效的SQL语句可能具有语法错误,或者引用了在编译时不存在的表或列。

    &sql指令可以在括号内的任何位置包含SQL样式的注释,可以不包含SQL代码,或仅包含注释文本。如果&sql指令不包含SQL代码或仅包含注释文本,则将该指令解析为无操作,并且未定义SQLCODE变量

      NEW SQLCODE
      WRITE !,"Entering Embedded SQL"
      &sql()
      WRITE !,"Leaving Embedded SQL"
    
      NEW SQLCODE
      WRITE !,"Entering Embedded SQL"
      &sql(/* SELECT Name INTO :a FROM Sample.Person */)
      WRITE !,"Leaving Embedded SQL"
    

    &sql替代语法

    由于复杂的嵌入式SQL程序可能包含多个&sql指令(包括嵌套的&sql指令),因此提供了以下替代语法格式:

    • ## sql(...):此指令在功能上等同于&sql。它提供了另一种语法来使代码清晰。但是,它不能包含标记语法。
    • &sql <marker>(...)<reversemarker>:此伪指令允许指定多个&sql伪指令,并使用用户选择的标记字符或字符串标识每个伪伪指令。下一节将介绍此标记语法。

    &sql标记语法

    可以使用用户定义的标记语法来标识特定的&sql指令。该语法由在“&sql”和右括号之间指定的字符或字符串组成。在嵌入式SQL的结尾处,在右括号后必须立即显示此标记的相反内容。语法如下:

      &sql<marker>( SQL statement )<reverse-marker>
    

    请注意,在&sql,标记和右括号之间不允许有空格(空格,制表符或行返回),并且在右括号和反向标记之间不允许有空格。

    标记可以是单个字符或一系列字符。标记不能包含以下标点符号:

    ( + - / \ | * )
    

    标记不能包含空格字符(空格,制表符或换行符)。它可能包含所有其他可打印字符和字符组合,包括Unicode字符。标记和反向标记区分大小写。

    相应的反向标记必须包含与反向标记相同的字符。例如:&sqlABC(...)CBA 如果标记包含[或{字符,则反向标记必须包含相应的]或}字符。以下是有效的&sql标记和反向标记对的示例:

      &sql@@( ... )@@
      &sql[( ... )]
      &sqltest( ... )tset
      &sql[Aa{( ... )}aA]
    

    选择标记字符或字符串时,请注意以下重要的SQL限制:SQL代码不能在代码中的任何位置(包括文字字符串和注释)包含字符序列“)<reversemarker>”。例如,如果标记“ABC,则字符串“)CBA”不能出现在嵌入式SQL代码中的任何位置。如果发生这种情况,有效标记和有效SQL代码的组合将使编译失败。因此,在选择标记字符或字符串时要格外小心,以防止发生这种冲突,这一点很重要。

    嵌入式SQL和行偏移量

    嵌入式SQL的存在会影响ObjectScript行偏移量,如下所示:

    • 嵌入式SQL在例程中的该点处将INT代码行的总数加(至少)2。因此,嵌入式SQL的单行计为3行,嵌入式SQL的两行计为4行,依此类推。调用其他代码的嵌入式SQL可以向INT代码添加更多行。

    一个虚拟的嵌入式SQL语句,仅包含一个注释,算作2条INT代码行,如以下示例所示:&sql(/ *供将来使用* /)

    • 嵌入式SQL中的所有行都计为行偏移,包括注释和空白行。

    可以使用^ROUTINE全局显示INT代码行。

    展开全文
  • 一般书籍中关于powerbuilder调用SQL语句有介绍,但一般会存在出错的问题,主要需要有其他语句配套使用,或记录操作前的预处理。
  • 文章目录 第十二章 使用嵌入式SQL(三)主机变量主机变量示例用列号下标的主机变量`NULL`和未定义的主机变量主机变量的有效性主机变量和程序块 第十二章 使用嵌入式SQL(三) 主机变量 主机变量是将文字值传入或...
  • 嵌入式sql连接数据库

    2021-05-04 05:03:44
    嵌入式SQL编程的范例,使用VC6编译Oracle 10g 嵌入式SQL程序操作步骤一、 基本要求1、所需软件Visual C++ 6.02、 源代码包括PRO C 文件: student.pc3、安装ORACLE10G 或其客户端在ORACLE10G CLIENT 安装时并没有 ...
  • C语言中嵌入SQL的配置方法 一、软件安装及环境配置 1.将“DEVTOOLS”文件夹复制到“C:\Program Files\Microsoft SQL Server”。 2.初始化VC++编译器环境。在命令行方式下运行文件“\VC98\Bin\vcvars32.bat”。
  • 嵌入式SQL生成器

    2017-08-16 10:56:43
    用于生成嵌入式SQL替换语句,对于程序员有很大的帮助,提高开发效率。
  • 使用程序设计语言访问SQL:JDBC、从Python访问数据库、ODBC、嵌入式SQL
  • 嵌入式SQL 2008

    2017-12-20 21:50:12
    sql server 2008 嵌入式ppt 教学 sql server 2008 嵌入式ppt 教学
  • SQL笔记9.嵌入式SQL

    2022-04-07 14:03:26
    SQL嵌入到其它语言中,这个时候编译需要其他方法 1.扩充主语言编译系统,使之能够处理SQL语句 2.预处理:在编译前先扫描源程序,将SQL语句翻译成目标(或主语言程序)过程代码,并将SQL执行翻译成主语言的过程调用...
  • 数据库系统——第九讲 嵌入式SQL语言之基本技巧嵌入式SQL语言概述变量声明与数据库连接数据集与游标可滚动游标与数据库的增删改状态捕获及错误处理机制小结 嵌入式SQL语言概述 提示:这里可以添加本文要记录的大概...
  • 嵌入式SQL的使用技巧

    2021-02-01 22:18:08
    #MYSQL#本篇主要介绍的是嵌入式SQL的使用规则,和具体的使用方法。SQL语言可以嵌入到高级语言中,如PL1、COBOL、FORTRAN、 C,利用高级语言的过程性结构,可以弥补SQL语言在实现复杂应用方面的不足,在这种方式下使用...
  • 一、实验目的熟悉通过嵌入式SQL(主语言为C语言)编程访问数据库。二、实验平台和实验工具在KingbaseES数据库管理系统上,通过C语言编写访问数据库的应用程序来对数据库进行各种数据操作。编程工具VC++6.0另需要32位...
  • 1、嵌入式SQL 2、游标 3、存储过程
  • 嵌入式SQL与主语言的通信_MySQL

    千次阅读 2021-01-19 09:18:53
    SQL嵌入到高级语言中混合编程,程序中会含有两种不同计算模型的语句:(1)SQL语句:描述性的面向集合的语句;负责操纵数据库(2)高级语言语句:过程性的面向记录的语句;负责控制程序流程。工作单元之间的通信方式:...
  • 第15章 嵌入式SQL的应用 SQL在如今的数据库领域虽然应用的非常的广泛,但是,与一些高级语言相比,在某些功能上还有一定的限制。也就是说,在有些功能上,纯粹使用SQL语句还无法实现。数据库访问只是其中一个部件。...
  • 数据库系统概论的学习总结资料,xmind格式思维导图,嵌入式SQL的基本概念思维导图及png格式大图
  • 嵌入式SQL简介

    2013-07-19 14:31:22
    嵌入式SQL简介,说明语句举例,不用游标的DML语句举例等...
  • 静态SQL特点:SQL语句在程序中已经按要求写好,只需要把一些参数通过变量(高级语言程序语句中不带冒号) 传送给嵌入式SQL语句即可(嵌入式SQL语句中带冒号) SpecName = ‘张三’; exec sql select Sno, Sname, Sclass ...
  • 要求:使用嵌入SQL对数据库进行单表精确查询、模糊查询 主语言:Java 平台:Eclipse DBMS:SQL SERVER 2019 运行说明: (1)下载JDBC,配置路径。 (2)在SQL SERVER的配置管理器中启用TCP/IP连接服务,找到IP地址...
  • ORACLE基础学习----ORACLE傻瓜手册(第八章--嵌入式SQL)(2006-07-14 13:42:51)8 嵌入式SQL(C)所有程序例子都在附件08_proc/下。在C语言程序代码中直接嵌入SQL语句,使数据库编程变得非常简单明了,而且嵌入式SQL是一...
  • 关闭数据库连接 嵌入式SQL语句的基本格式 嵌入式SQL语句与主语言之间的通信 1.SQL通信区 2.主变量 3.游标 查询结果为多条记录的SELECT语句 1.申明游标 2.打开游标 3.推进游标指针并取当前记录 4.关闭游标 CURRENT...
  • 让我在OO语言中使用SQL的一件事就是必须在字符串中定义SQL语句.当我以前在IBM大型机上工作时,这些语言使用SQL预处理器来解析本机代码中的SQL语句,因此语句可以用明文SQL编写而不会混淆字符串,例如在Cobol中有一个...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 53,664
精华内容 21,465
关键字:

嵌入式sql

友情链接: 4.zip