⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 esqlc方面的资料.txt

📁 db2 指定某个字符串中的第几个字符的更新
💻 TXT
📖 第 1 页 / 共 5 页
字号:
{
   EXEC SQL FETCH c1 INTO :fname, :lname;
   if (SQLCODE == 0)
   {
       printf("%12s %12s\n", fname, lname);
       printf("Delete? ");
       scanf("%c", &reply);
       if (reply == 'y')
       {
           EXEC SQL DELETE FROM authors WHERE CURRENT OF c1;
           printf("delete sqlcode= %d\n", SQLCODE(ca));
       }
   }
}
EXEC SQL CLOSE c1;
2.3.5 SQLCA
    DBMS是通过SQLCA(SQL通信区)向应用程序报告运行错误信息。SQLCA是一个含有错误变量和状态指示符的数据结构。通过检查SQLCA,应用程序能够检查出嵌入式SQL语句是否成功,并根据成功与否决定是否继续往下执行。预编译器自动会在嵌入SQL语句中插入SQLCA数据结构。在程序中可以使用EXEC SQL INCLUDE SQLCA,目的是告诉SQL预编译程序在该程序中包含一个SQL通信区。也可以不写,系统会自动加上SQLCA结构。
   下表是SQLCA结构中的变量和作用: 

变量             数据类型               作用 

sqlcaid             char            包含“sqlca”的字符串
sqlcabc             long            SQLCA的长度
sqlcode             long           包含最近一次语句执行的返回代码
sqlwarn[0] 到
sqlwarn[7]           char           警告标志。如果是“W”,那么表示有警报信息。
sqlerrm.sqlerrmc[ ]   char            错误信息。
sqlerrm.sqlerrml     long            错误信息的长度。
sqlerrp             char            检测错误或警告信息的过程。
sqlerrd[6]           long            警告或错误的详细信息。[2]中存放影响行的个数。 

  下面仔细讲解几个重要的变量。
1)、SQLCODE
   SQLCA结构中最重要的部分是SQLCODE变量。在执行每条嵌入式SQL语句时,DBMS在SQLCA中设置变量SQLCODE值,以指明语句的完成状态:
1、0该语句成功执行,无任何错误或报警。
2、<0        出现了严重错误。
3、>0        出现了报警信息。
4、100没有数据存在。在FETCH语句中,表示到达结果集的末尾。在UPDATE、
            DELETE、INSERT语句中,表示没有满足条件的数据。
例:显示错误信息。
printf("\nError occurred: code %d.\n%s",
sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
  在SYBASE SQL SERVER中,也可以单独定义SQLCODE。如:
long SQLCODE;
exec sql open cursor pub_id;
while (SQLCODE == 0)
{
exec sql fetch pub_id into :pub_name;
….. 

2)、SQLSTATE
SQLSTATE变量也是SQLCA结构中的成员。它同SQLCODE一样,都是返回错误信息。SQLSTATE是在SQLCODE之后产生的。这是因为,在制定SQL2标准之前,各个数据库厂商都采用SQLCODE变量来报告嵌入式SQL语句中的错误状态。但是,各个厂商没有采用标准的错误描述信息和错误值来报告相同的错误状态。所以,标准化组织增加了SQLSTATE变量,规定了通过SQLSTATE变量报告错误状态和各个错误代码。因此,目前使用SQLCODE的程序仍然有效,但也可用标准的SQLSTATE错误代码编写新程序。值得注意的是,Open client emebeded SQL/C11.1.x并不完全支持SQLSTATE。
SQLSTATE是一个字符串参数。具体含义如下: 

值                    作用 

00XXX                     成功
01XXX                     警告
02XXX                     不存在数据
其他值                     错误 

2.3.6 WHENEVER
  在每条嵌入式SQL语句之后立即编写一条检查SQLCODE/SQLSTATE值的程序,是一件很繁琐的事情。为了简化错误处理,可以使用WHENEVER语句。该语句是SQL预编译程序的指示语句,而不是可执行语句。它通知预编译程序在每条可执行嵌入式SQL语句之后自动生成错误处理程序,并指定了错误处理操作。
  用户可以使用WHENEVER语句通知预编译程序去如何处理三种异常处理:
lWHENEVER SQLERROR action:表示一旦sql语句执行时遇到错误信息,则执行action,action中包含了处理错误的代码(SQLCODE<0)。
lWHENEVER SQLWARNING action:表示一旦sql语句执行时遇到警告信息,则执行aciton,即action中包含了处理警报的代码(SQLCODE=1)。
lWHENEVER NOT FOUND action:表示一旦sql语句执行时没有找到相应的元组,则执行action,即action包含了处理没有查到内容的代码(SQLCODE=100)。
   针对上述三种异常处理,用户可以指定预编译程序采取以下三种行为(action):
lWHENEVER …GOTO:通知预编译程序产生一条转移语句。
lWHENEVER…CONTINUE:通知预编译程序让程序的控制流转入到下一个主语言语句。
lWHENEVER…CALL:通知预编译程序调用函数。
其完整语法如下:
    WHENEVER {SQLWARNING | SQLERROR | NOT FOUND} {CONTINUE | GOTO stmt_label | CALL function()}
例:WHENEVER的作用
EXEC SQL WHENEVER sqlerror GOTO errormessage1;
EXEC SQL DELETE FROM homesales
   WHERE equity < 10000;
EXEC SQL DELETE FROM customerlist
   WHERE salary < 40000;
EXEC SQL WHENEVER sqlerror CONTINUE;
EXEC SQL UPDATE homesales
   SET equity = equity - loanvalue;
EXEC SQL WHENEVER sqlerror GOTO errormessage2;
EXEC SQL INSERT INTO homesales (seller_name, sale_price)
   real_estate('Jane Doe', 180000.00);
       .
       .
       .
errormessage1:
   printf("SQL DELETE error: %ld\n, sqlcode);
exit(); 

errormessage2:
   printf("SQL INSERT error: %ld\n, sqlcode);
exit();
WHENEVER语句是预编译程序的指示语句。在上面这个例子中,由于第一个WHENEVER语句的作用,前面两个DELETE语句中任一语句内的一个错误会在errormessage1中形成一个转移指令。由于一个WHENEVER语句替代前面WHENEVER语句,所以,嵌入式UPDATE语句中的一个错误会直接转入下一个程序语句中。嵌入式INSERT语句中的一个错误会在errormessage2中产生一条转移指定。
从上面例子看出,WHENEVER/CONTINUE语句的主要作用是取消先前的WHENEVER语句的作用。WHENEVER语句使得对嵌入式SQL错误的处理更加简便。应该在应用程序中普遍使用,而不是直接检查SQLCODE的值。
2.3.7 批处理
嵌入SQL也支持批处理。如:
exec sql insert into TABLE1 values (:val1)
          insert into TABLE2 values (:val2)
     insert into TABLE3 values (:val3);
  SYBASE SQL SERVER将在EXEC SQL和“;”之间的所有T-SQL语句作为一个批来处理。在上例中,会将这3个语句作为一组来处理。
2.3.8 事务
SYBASE SQL SERVER预编译器能够处理两种事务模式:ANSI/ISO事务模式和T-SQL模式。在T-SQL模式中,除非有begin transaction外,每个语句都会做提交。可以在编译时设置事务模式。ANSI/ISO模式是系统的缺省模式。嵌入SQL的事务语法和T-SQL的事务语法是相同的。
2.3.8.1 T-SQL事务模式
1)、开始事务
 exec sql [at connect_name]
begin transaction [ transaction_name];
2)、保存事务回滚点
exec sql [at connect_name]
save transaction [ savepoint_name];
3)、提交事务
exec sql [at connect_name] commit transaction
[ transaction_name];
4)、回滚事务
exec sql [at connect_name] rollback transaction
[ savepoint_name | transaction_name];
2.3.8.2 ANSI/ISO事务模式
   该模式没有begin transaction和save transaction。在应用程序中,只要遇到以下语句,就表示事务开始:delete、insert、select、update、open和exec。当遇到commit work或rollback work,就表示事务结束。也就是说,commit和rollback表示当前事务结束,下一个事务开始。
2.4动态SQL语句
前一节中讲述的嵌入SQL语言都是静态SQL语言,即在编译时已经确定了引用的表和列。主变量不改变表和列信息。在上几节中,我们使用主变量改变查询参数,但是不能用主变量代替表名或列名。否则,系统报错。动态SQL语句就是来解决这个问题。
动态SQL语句的目的是,不是在编译时确定SQL的表和列,而是让程序在运行时提供,并将SQL语句文本传给DBMS执行。静态SQL语句在编译时已经生成执行计划。而动态SQL语句,只有在执行时才产生执行计划。动态SQL语句首先执行PREPARE语句要求DBMS分析、确认和优化语句,并为其生成执行计划。DBMS还设置SQLCODE以表明语句中发现的错误。当程序执行完“PREPARE”语句后,就可以用EXECUTE语句执行执行计划,并设置SQLCODE,以表明完成状态。
  使用动态SQL,共分成四种方法: 

方法     支持的SQL语句                                      实现方法 

1        该语句内不包含宿主变量,该语句不是查询语句       execute immediate
2        该语句内包含输入宿主变量 ,该语句不是查询语句    prepare和execute
3        包含已知数目的输入宿主变量或列的查询           prepare和fetch
4        包含未知数目的输入宿主变量或列的查询           prepare和fetch,用描述符 

按照功能和处理上的划分,动态SQL应该分成两类来解释:动态修改和动态查询。方法1和方法2完成动态修改(参见2.4.1)。方法3和方法4完成了动态查询(参见2.4.2和2.4.3)。    
2.4 .1 动态修改
方法1和方法2完成动态修改。对于方法1,表示要执行一个完整的T-SQL语句,该语句没有宿主变量,不是一个查询语句。因为没有宿主变量来带入不同的参数,所以不能通过方法1来重复执行修改语句。具体语法为:
exec sql [at connection_name] execute immediate
{: host_variable | string};
其中,host_variable和string是存放完整T-SQL语句。
例:提示用户输入被更新书的条件,然后组合成为一个完整的SQL语句,并执行更新。
exec sql begin declare section;
CS_CHAR sqlstring[200];
exec sql end declare section;
char cond[150];
exec sql whenever sqlerror call err_p();
exec sql whenever sqlwarning call warn_p();
strcpy(sqlstring,
"update titles set price=price*1.10 where ");
printf("Enter search condition:");
scanf("%s", cond);
strcat(sqlstring, cond);
exec sql execute immediate :sqlstring;
exec sql commit work;
对于方法2,可以执行一个包含输入宿主变量的动态修改语句。该方法要使用PREPARE语句和EXECUTE语句。PREPARE语句是动态SQL语句独有的语句。其语法为:
   PREPARE 语句名  FROM 宿主变量|字符串
该语句接收含有SQL语句串的宿主变量,并把该语句送到DBMS。DBMS编译语句并生成执行计划。在语句串中包含一个“?”表明参数,当执行语句时,DBMS需要参数来替代这些“?”。PREPRARE执行的结果是,DBMS用语句名标志准备后的语句。SQL SERVER编译后的语句以临时存储过程的形式存放在缓冲区中。语句名类似于游标名,是一个SQL标识符。在执行SQL语句时,EXECUTE语句后面是这个语句名。请看下面这个例子:
EXEC SQL BEGIN DECLARE SECTION;
char        prep[] = "INSERT INTO mf_table VALUES(?,?,?)";
char        name[30];
char        car[30];
double         num;
EXEC SQL END DECLARE SECTION;
EXEC SQL PREPARE prep_stat FROM :prep;
while (SQLCODE == 0)
{
   strcpy(name, "Elaine");
   strcpy(car, "Lamborghini");
   num = 4.9;
   EXEC SQL EXECUTE prep_stat USING :name, :car, :num;
}
  在这个例子中,prep_stat是语句名,prep宿主变量的值是一个INSERT语句,包含了三个参数(3个“?”)。PREPARE的作用是,DBMS编译这个语句并生成执行计划,并把语句名标志这个准备后的语句。值得注意的是,PREPARE中的语句名的作用范围为整个程序,所以不允许在同一个程序中使用相同的语句名在多个PREPARE语句中。
   EXECUTE语句是动态SQL独有的语句。它的语法如下:
EXECUTE 语句名 USING  宿主变量 | DESCRIPTOR 描述符名
请看上面这个例子中的“EXEC SQL EXECUTE prep_stat USING :name, :car, :num;”语句,它的作用是,请求DBMS执行PREPARE语句准备好的语句。当要执行的动态语句中包含一个或多个参数标志时,在EXECUTE语句必须为每一个参数提供值,如::name、:car和:num。这样的话,EXECUTE语句用宿主变量值逐一代替准备语句中的参数标志(“?”),从而,为动态执行语句提供了输入值。
使用主变量提供值,USING子句中的主变量数必须同动态语句中的参数标志数一致,而且每一个主变量的数据类型必须同相应参数所需的数据类型相一致。各主变量也可以有一个伴随主变量的指示符变量。当处理EXECUTE语句时,如果指示符变量包含一个负值,就把NULL值赋予相应的参数标志。除了使用主变量为参数提供值,也可以通过SQLDA提供值(见节2.4.4)。
2.4.2 动态游标
使用动态游标可以完成方法3。
   游标分为静态游标和动态游标两类。对于静态游标,在定义游标时就已经确定了完整的SELECT语句。在SELECT语句中可以包含主变量来接收输入值。当执行游标的OPEN语句时,主变量的值被放入SELECT语句。在OPEN语句中,不用指定主变量,因为在DECLARE CURSOR语句中已经放置了主变量。请看下面静态游标的例子:
EXEC SQL BEGIN DECLARE SECTION;
char szLastName[] = "White";
char szFirstName[30];
EXEC SQL END DECLARE SECTION; 

EXEC SQL
   DECLARE author_cursor CURSOR FOR
   SELECT au_fname FROM authors WHERE au_lname = :szLastName; 

EXEC SQL OPEN author_cursor; 

EXEC SQL FETCH author_cursor INTO :szFirstName;
动态游标和静态游标不同。以下是动态游标使用的句法(请参照本小节后面的例子来理解动态游标)。
1)、声明游标:
 对于动态游标,在DECLARE CURSOR语句中不包含SELECT语句。而是,定义了在PREPARE中的语句名,PREPARE语句规定与查询相关的语句名称。具体语法为:
exec sql [at connection_name] declare cursor_name
cursor for statement_name;
如:EXEC SQL DECLARE author_cursor CURSOR FOR select_statement;
值得注意的是,声明动态游标是一个可执行语句,应该在PREPARE语句后执行。
2)、打开游标
完整语法为:OPEN 游标名 [USING 主变量名 | DESCRIPTOR 描述名]
   在动态游标中,OPEN语句的作用是使DBMS定位相关的游标在第一行查询结果前。当OPEN语句成功执行完毕后,游标处于打开状态,并为FETCH语句做准备。OPEN语句执行一条由PREPARE语句预编译的语句。如果动态查询正文中包含有一个或多个参数标志时,OPEN语句必须为这些参数提供参数值。USING子句的作用就是规定参数值。可以使用主变量提供参数值,也可以通过描述名(即SQLDA)提供参数值。如:EXEC SQL OPEN author_cursor USING :szLastName;。
3)、取一行值
   FETCH语法为:FETCH 游标名 INTO USING DESCRIPTOR 描述符名。
动态FETCH语句的作用是,把游标移到下一行,并把这一行的各列值送到SQLDA中。注意的是,静态FETCH语句的作用是用主变量表接收查询到的列值。在方法3中,使用的是静态FETCH语句获得值。动态FETCH语句只在方法4中使用。
4)、关闭游标
如:EXEC SQL CLOSE c1;
关闭游标的同时,会释放由游标添加的锁和放弃未处理的数据。在关闭游标前,该游标必须已经声明和打开。另外,程序终止时,系统会自动关闭所有打开的游标。
总之,在动态游标的DECLARE CURSOR语句中不包含SELECT语句。而是,定义了在PREPARE中的语句名,用PREPARE语句规定与查询相关的语句名称。当PREPARE语句中的语句包含了参数,那么在OPEN语句中必须指定提供参数值的主变量或SQLDA。动态DECLARE CURSOR语句是一个可执行语句。该子句必须在OPEN、FETCH、CLOSE语句之前使用。请看下面这个例子,描述了完成方法3的五个步骤:PREPARE、DECLARE、OPEN、FETCH和CLOSE。
……
EXEC SQL BEGIN DECLARE SECTION;
char szCommand[] = "SELECT au_fname FROM authors WHERE au_lname = ?";
char szLastName[] = "White";
char szFirstName[30];
EXEC SQL END DECLARE SECTION;
EXEC SQL  PREPARE select_statement FROM :szCommand;
EXEC SQL DECLARE author_cursor CURSOR FOR select_statement;
EXEC SQL OPEN author_cursor USING :szLastName;
EXEC SQL FETCH author_cursor INTO :szFirstName;
EXEC SQL CLOSE author_cursor;
………
 下面是一个实现方法3的实际例子。提示用户输入排序的条件,并把符合条件的书信息显示出来。
……
exec sql begin declare section;
CS_CHAR sqlstring[200];
CS_FLOAT bookprice,condprice;
CS_CHAR booktitle[200];
exec sql end declare section;
char orderby[150];
exec sql whenever sqlerror call err_p();
exec sql whenever sqlwarning call warn_p();
strcpy(sqlstring,
"select title,price from titles\
where price>? order by ");
printf("Enter the order by clause:");
scanf("%s", orderby);
strcat(sqlstring, orderby);
exec sql prepare select_state from :sqlstring;
exec sql declare select_cur cursor for
select_state;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -