《实际开发中的proc教程ppt课件.ppt》由会员分享,可在线阅读,更多相关《实际开发中的proc教程ppt课件.ppt(77页珍藏版)》请在三一办公上搜索。
1、PROC/C+课程,PROC/C+,Points,3. 宿主变量与指示变量,4. 嵌入SQL语句,5. 连接数据库,6. 错误处理,1. PROC简介,7. 数据的存取更新操作,8. 动态sql,2. PROC程序的编写步骤,Pro程序,通过在过程化编程语言中嵌入SQL语句而开发出的应用程序称为Pro程序。在通用编程语言中使用的SQL称为嵌入式SQL在SQL标准中定义了多种语言的嵌入式SQL各个厂商对嵌入式SQL的具体实现不同,宿主语言 Pro程序C/C+ Pro*C/C+FORTRAN Pro*FORTRANPASCAL Pro*PASCALCOBOL Pro*COBOLPL/I Pro*P
2、L/IAda Pro*Ada,Pro*C/C+程序,在C/C+语言中嵌入SQL语句而开发出的应用程序称为Pro*C/C+程序。目的:使c/c+这种高效率语言成为访问数据库的工具。,Pro*C程序实例,#includeEXEC SQL BEGIN DECLARE SECTION;char username20;char password20;char last_name25;EXEC SQL END DECLARE SECTION;EXEC SQL INCLUDE sqlca;void sqlerror();main() EXEC SQL WHENEVER SQLERROR DO sqlerro
3、r(); strcpy(username,tarena); strcpy(password, tarena); EXEC SQL CONNECT:username IDENTIFIED BY:password;,EXEC SQL select LAST_NAME into :last_name from S_EMP where id=2; printf(nID=2,last_name=%sn , last_name);void sqlerror() EXEC SQL WHENEVER SQLERROR CONTINUE; printf(n- oracle error detected:n);
4、printf(%.70sn, sqlca.sqlerrm.sqlerrmc); EXEC SQL ROLLBACK WORK RELEASE; exit(1);,Include 头文件 (c/c+ and pro*c/c+)定义变量定义函数main 连结数据库: connectSQL 操作语句: EXEC SQL .;exception handler断开连结: EXEC SQL COMMIT / ROLLBACK WORK release,PROC程序结构,一般应用程序(C)开发运行标准流程,.c文件,.o文件,可执行文件,% vi a_1.c a_2.c% gcc c a_1.c a_2.
5、c% gcc -oa a_1.o a_2.o,一般应用程序(C)开发运行标准流程,Pro*C程序开发运行流程,.o文件,可执行文件,.pc文件,.c文件,完成Pro*C源程序到纯C源程序的转换基本命令格式PROC INAME=filename OptionName1=value1OptionNameN=valueN,Pro*C预编译程序,PROC常用预编译选项,INAME=path and filename (name of the input file)ONAME=path and filename (name of the output file)INCLUDE=path (头文件所在路径
6、)-INCLUDE =路径名 或 INCLUDE =(路径名1,路径名2)PARSE=FULL | PARTIA | NONE (default FULL for C, Others for C+)CODE=ANSI_C | CPP (default ansi_c)USERID=username/password,Pro*C程序开发运行流程,#includeEXEC SQL BEGIN DECLARE SECTION;char user_passwd20;EXEC SQL END DECLARE SECTION;EXEC SQl include sqlca;main() EXEC SQL WH
7、ENEVER SQLERROR stop; strcpy(user_passwd,tarena/tarena); EXEC SQL CONNECT:user_passwd; printf(nConnected to ORACLE as user:%sn , user_passwd);,Pro*C程序开发运行流程% vi a.pc% proc a.pc% gcc -o a a.c -lclntsh -Compare Pro*C and its C code,Pro*C+预编译程序,Pre-compile:proc myf.pc oname=myf.cpp parse=none code=cpp2
8、. Compile:g+ -omyfile myfile.cpp lclntsh3. Execute:myfile,#include Using namespace std;EXEC SQL BEGIN DECLARE SECTION;char user_passwd20;EXEC SQL END DECLARE SECTION;EXEC SQl include sqlca;main() EXEC SQL WHENEVER SQLERROR stop; strcpy(user_passwd,tarena/tarena); EXEC SQL CONNECT:user_passwd; coutCo
9、nnected to ORACLE as user “ , user_passwd;,宿主变量,宿主变量是一种pro*c语言变量, 用于在应用程序中和oracle数据库之间传递数据。Pro*C程序中,既可在SQL语句中引用,也可在C语句中引用的变量称为SQL变量。,C语言语句群,SQL语言语句群,宿主变量,宿主变量的数据类型,数据类型描述char单字符charnN个定长字符数组int整数short 短整数long长整数float单精度浮点数double双精度浮点数VARCHARn变长字符串,宿主变量的使用,输入 - 将应用程序的数据传递到数据库中。int salary, emp_number;
10、 cinsalary; cinemp_number;EXEC SQL update emp set sal=:salary where empno= :emp_number;输出 - 将数据库的数据传递到应用程序中。float v_salary;char v_job; EXEC SQL select sal,job INTO :v_salary, :v_job from emp where empno = 7788;coutv_salaryv_job;,处理字符数据,预编译选项 CHAR_MAP CHAR_MAP=CHARZ (默认设置):0结尾,定长,空格补齐。 CHAR_MAP=CHARF
11、 | VARCHAR2:定长,空格补齐。 CHAR_MAP=STRING: 0结尾,变长。 当0结尾,宿主变量长度要大于实际数据长度。 VARCHAR1.变长, 不是0结尾。2. Struct unsigned short len; unsigned char arr variable_name;,使用宿主变量的注意事项,其申明语法与普通C变量一致,但在CODE=CPP或 MODE=ANSI 时变量必须放在申明区.可使用pointer 作为宿主变量,使用前分配空间。在DDL语句中不能用宿主变量。错误例子:char table_name30;cintable_name;EXEC SQL DROP
12、 TABLE :table_name;,指示变量,指示变量(indicator variable)短整型变量,用于处理数据库的NULL值,监督和管理与其相关联的宿主变量。引用语法::host_variable INDICATOR :indicator_variableOR:host_variable:indicator_variable,指示变量的作用,主要用在输出, 即当宿主变量用于接收数据库的返回数据时。通过在宿主变量后用指示变量, 检测是否返回了NULL。-1:数据库表列的值为NULL,指示变量相关联的输出宿主变量值不确定=0:Oracle将数据库表列值原封不动的赋给指示器变量相关联的输
13、出宿主变量0: Oracle将数据库表列值截断后赋给指示器变量相关联的输出宿主变量,指示器变量值为该列值的原始长度,指示变量例子,EXEC SQL BEGIN DECLARE SECTION; int m_id; short ind_m_id;EXEC SQL END DECLARE SECTION;EXEC SQL SELECT manager_id INTO :m_id:ind_m_id FROM s_emp WHERE id=1;If(ind_m_id =-1) cout“emp_desc is NULL”endl;else cout m_id endl;,数组变量,Pro*C只支持一维
14、数组Pro*C不支持数组指针Pro*C所支持数组最大维数是32767,超出此限制将报错示例EXEC SQL BEGIN DECLARE SECTION;int A100;char B100;char C10015; EXEC SQL END DECLARE SECTION;,数组变量,在SQL语句中使用数组变量,只需给出:和变量名称, 不要给下标。示例EXEC SQL BEGIN DECLARE SECTION;int emp_number100;char emp_name10015;EXEC SQL END DECLARE SECTION; EXEC SQL SELECT number,na
15、me INTO :emp_number, :emp_name FROM emp;,数组变量,错误的例子:for(int i = 0;i 100; i +) EXEC SQL SELECT number,name INTO :emp_numberi, :emp_namei; 指示器数组例子:EXEC SQL BEGIN DECLARE SECTION;int emp_number100;char emp_name10015;short ind_emp_number100;EXEC SQL END DECLARE SECTION;EXEC SQL SELECT number,name INTO :
16、emp_number:ind_emp_number,:emp_name;,通信区说明 (SQLCA),SQLCA 是ORACLE提供的两个通信区之一。SQLCA实际上是一个结构变量,其目的是为了诊断错误和事件处理结果。SQLCA的结构struct sqlca /* ub1 */ char sqlcaid8; /* b4 */ int sqlabc; /* b4 */ int sqlcode; struct /* ub2 */ unsigned short sqlerrml; /* ub1 */ char sqlerrmc70; sqlerrm; /* ub1 */ char sqlerrp8;
17、 /* b4 */ int sqlerrd6; /* ub1 */ char sqlwarn8; /* ub1 */ char sqlext8; ;,通信区说明 (SQLCA),sqlcaid8 用于标识一个SQLCAsqlabc 用于保存SQLCA的长度sqlcode用于保存最近一次运行SQL指令的状态0 正常 0有一个异常发生 0系统错误,可能来自网络,或数据库本身sqlerrm. sqlerrml保存错误文本信息的长度sqlerrm. sqlerrmc保存错误文本信息,最长为70个字符sqlerrp 系统保留sqlerrd60,1,3,5系统保留2当前SQL指令处理的行数4保存相对位移,
18、指出在什么地方出现语法错误,通信区说明 (SQLCA),sqlwarn80指示是否设置了警告标志1指示是否将字符结果返回给宿主变量时,数据截短了3如果查询时,返回的列数和指定的宿主数组变量的维数不等时设置该位4UPDATE和DELETE时没有行被处理,设置改标志位5当EXEC SQL CREATE PROCEDURE|FUNCTION|PACKAGE|PACKAGE BODY失败时,设置该位2,6,7系统保留sqlext8 系统保留,int main()EXEC SQL INCLUDE sqlca;EXEC SQL WHENEVER SQLERROR Do err_report(sqlca);
19、 void err_report( struct sqlca sqlca) if (sqlca.sqlcode 0) printf(n%d%snn,sqlca.sqlerrm.sqlerrml ,sqlca.sqlerrm.sqlerrmc); exit(1); ,SQLCA应用实例,通信区说明 ( ORACA),当需要更进一步的信息时,ORACA将帮助我们达成愿望,所以ORACA也可以看作时SQLCA的补充和辅助。,通信区说明 ( ORACA),struct oraca /* text */ char oracaid8; /* Reserved */ /* ub4 */ int oracab
20、c; /* Reserved */ /* ub4 */ int oracchf; /* 0 if check cur cache consistncy*/ /* ub4 */ int oradbgf; /* 0 if do DEBUG mode checking */ /* ub4 */ int orahchf; /* 0 if do Heap consistency check */ /* ub4 */ int orastxtf; /* SQL stmt text flag */struct /* ub2 */ unsigned short orastxtl; /* text */ char
21、 orastxtc70; orastxt; /* text of last SQL stmt */ struct /* ub2 */ unsigned short orasfnml; /* text */ char orasfnmc70; orasfnm; /* name of file containing SQL stmt */ /* ub4 */ int oraslnr; /* line nr-within-file of SQL stmt */ /* ub4 */ int orahoc; /* highest max open OraCurs requested */ /* ub4 *
22、/ int oramoc; /* max open OraCursors required */ /* ub4 */ int oracoc; /* current OraCursors open */ /* ub4 */ int oranor; /* nr of OraCursor re-assignments */ /* ub4 */ int oranpr; /* nr of parses */ /* ub4 */ int oranex; /* nr of executes */ ;,通信区说明 ( ORACA),oracaid8 标识一个ORACA通信区oracabc用于保存ORACA通信
23、区的长度oradbgf调试标志,0关闭,1开启oracchf如果oradbgf1,那oracchf遵循下列规则:0禁止光标缓冲一致性检查1进行光标缓冲一致性检查orahchf如果oradbgf1,那oracchf遵循下列规则:0禁止堆缓冲一致性检查1进行堆缓冲一致性检查orastxtf可以是以下各值:0不保存SQL文本1仅对SQLERROR保存SQL文本2仅对SQLERROR和SQLWARNING保存SQL文本3总是保存SQL文本,通信区说明 ( ORACA),要使用ORACA,那么就要显式的加载ORACA结构到Pro*C程序中。可通过语句EXEC SQL INCLUDE oraca;EXEC
24、 ORACLE OPTION(ORACA=YES);实现。,嵌入SQL语句,EXEC SQL INSERT dept( 1, 人事部, 中鼎大厦7层 );,EXEC SQL sql-statement;,形式:,示例:,单个SQL语句的嵌入语法,嵌入事务控制语句,事务控制语句Commit, rollback and savepoint.EXEC SQL commit;EXEC SQL commit work release;EXEC SQL rollback work release;,嵌入事务控制语句,EXEC SQL SAVEPOINT savepoint_insert;for( i =
25、1; i 100; i+ ) getInput1( empName, ,数据操作语句(DML)语句列表EXEC SQL Select .;EXEC SQL Insert .;EXEC SQL update .;EXEC SQL Delete .;,嵌入DML语句,数据定义语句(DDL): create, alter, dropExample:EXEC SQL CREAT TABLE t1(cola int);EXEC SQL DROP TABLE t1;EXEC SQL ALTER TABLE t1 add(faxno number);对象名, 列名不能用宿主变量.自动提交事务,嵌入DDL语句
26、,嵌入PL/SQL语句,PL/SQL的嵌入语法,/*/EXEC SQL EXECUTE BEGIN /* PL/SQL BLOCK */ END;END-EXEC;/*/,形式:,嵌入PL/SQL的语法,PL/SQL的嵌入匿名块(anonymous blocks),/*- begin PL/SQL block -*/ EXEC SQL EXECUTE BEGIN SELECT job, hiredate, sal INTO :job_title, :hire_date, :salary FROM emp WHERE empno = :emp_number; DELETE from emp wh
27、ere empno = :emp_number; END; END-EXEC; /*- end PL/SQL block -*/,调用PL/SQL语句,PL/SQL的嵌入package,procedure,function,EXEC SQL EXECUTE BEGIN emp_action.raise_salary( :empNo, :increase ); END; END-EXEC;,Create or replace package emp_action is procedure raise_salary( empNO number, increase number);End emp_a
28、ction;,PL/SQL程序:,Pro*C程序:,先有连结, 后才能访问数据库.连结的方法:连结本地或远程数据库连结一个或多个数据库,连接数据库,EXEC SQL CONNECT :user IDENTIFIED BY :pswd | :usr_psw AT dbname | :host_variable USING :connect_string ALTER AUTHORIZATION :newpswd ;,Connect 语法形式,连接本地数据库,本地: 客户应用程序与oracle server 在同一台机器上.方式一:用户名口令由两个独立变量存储,Char userName20 = “
29、scott”;Char userPwd20 = “tiger”;EXEC SQL CONNECT :userName IDENTIFIED BY :userPwd;,Char uname_pwd40 = “scott/tiger”;EXEC SQL CONNECT :uname_pwd;,方式二:用户名口令由单个变量存储,连接远端数据库,远端: 客户应用程序与oracle server 不在同一台机器上.,char userPwd20 = “scott / tiger”;char dbString20 = “remoteDB”;EXEC SQL CONNECT : userPwd Using
30、:dbString;,remoteDB 是网络服务名, 在 $ORACLE_HOME/network/admin/tnsnames.ora文件中定义.,连接方式:,使用数据库链访问远端数据库,Char name25 = “scott smith”;/* 修改本地数据库区*/EXEC SQL update emp set sal=:salary where ename=:name;/* 修改远端数据库区*/EXEC SQL update empmyLink set sal=:salary where ename=:name;EXEC SQL commit work release;,CREATE
31、 DATABASE LINK myLink CONNECT TO tarena IDENTIFIED BY tarena Using tlab1;,用SQLPLUS创建数据库链接:,连接多个数据库,应用程序,Net8,一个程序同时连接多个数据库或者建立多个连接到同一个数据库,连接多个数据库,char user110 = scott / tiger ,db110 = ora1“, dbString120 = “oracle1”;char user210 = scott / tiger “, db210 = ora2“, dbString220 = “oracle2”;/*/EXEC SQL CO
32、NNECT :user1 AT :db1 Using :dbString1;EXEC SQL CONNECT :user2 AT :db2 Using :dbString2;Char name25 = “scott smith”;/* 修改db1数据库区*/EXEC SQL AT :db1 update emp set sal=:salary where ename=:name;/* 修改db2数据库区*/EXEC SQL AT :db2 update emp set sal=:salary where ename=:name;EXEC SQL AT :db1 commit work rele
33、ase; EXEC SQL AT :db2 commit work release;,使用数据库链访问远端数据库,应用程序,Net8,数据库链是在本地数据库和远端数据库之间的一种指针. 使用它可以在不同数据库的SQL语句和事务之间建立关联关系。,SQLCA与错误处理,为了给用户和开发人员提供oracle error message, Oracle 建议使用SQL通讯区(SQLCA).SQLCA is a C struct, 纪录每个当前SQL语句的执行状态,以便进行错误诊断和事件处理。#include OREXEC SQL INCLUDE SQLCA;,SQLCA通讯区,SQLCA的信息结构,
34、struct sqlca char sqlcaid8;long sqlcabc;long sqlcode;struct unsigned short sqlerrml;charsqlerrmc70; sqlerrm;char sqlerrp8;long sqlerrd6;char sqlwarn8;char sqlext8;,WHENEVER 语句,检测并处理sql语句错误。语法:EXEC SQL WHENEVER condition: SQLWARNING, SQLERROR, NOT FOUND.action: CONTINUE, DO, GOTO, STOP,BREAKExample:
35、EXEC SQL WHENEVER SQLWARNING CONTINUE; EXEC SQL WHENEVER SQLERROR DO sqlerror( ); EXEC SQL WHENEVER NOT FOUND DO notfound( );,WHENEVER 语句的管辖范围,自动检查所有后面的SQL statements. 一般放在Before first SQL statement.If using more than one WHENEVER, 只有最近的 WHENEVER起作用。,一般的错误处理方法,用WHENEVER 检查sql语句错误用SQLCA描述错误Rollback 所
36、有的操作,release 资源.,错误处理实例,.void sqlerror();Main()EXEC SQL WHENEVER SQLERROR DO sqlerror();EXEC SQL CONNECT:username IDENTIFIED BY:password;EXEC SQL update emp set comission=200 where emp_no=2; .void sqlerror() EXEC SQL WHENEVER SQLERROR CONTINUE; cout n- oracle error detected: sqlca.sqlerrm.sqlerrmc;
37、EXEC SQL ROLLBACK WORK RELEASE; exit(1);,用单个变量操作单行单列用多个变量或结构(struct )操作单行多列用 数组(array)或 游标(cursor) 操作多行多列,数据的存取更新操作,用单个变量操作单行单列,char ename35;int empno=20;EXEC SQL select emp_name INTO :ename from emp where emp_no=:empno;cout“the name is “ ename;注意事项:字符串长度定义指示变量的运用,char v_name31, char v_job21;float v
38、_salary;int empno=20;EXEC SQL select emp_name,job,salaryINTO :v_name,:v_job,:v_salaryFROM emp WHERE emp_no=:empno;coutv_name v_jobv_salary;注意事项:变量顺序与字段名一至,用多个变量操作单行多列,宿主结构是指包含多个宿主变量的C语言结构,以此可简化单行多列操作。Structintno;charname10;intsalary;emp_record;输入:EXEC SQL INSERT INTO emp(empno,ename,sal) VALUES (:em
39、p_record);输出: EXEC SQL SELECT empno,ename,sal INTO :emp_recordWHERE rownum=1;,用结构(struct )操作单行多列,注意事项: 可用结构pointer,但要分配空间。结构成员的数据类型,顺序必须与SQL语句一至。不能用嵌套的结构。不能用C联合(UNION),用结构(struct )操作单行多列,目的: 降低网络开销,提高程序性能。数组和 INSERT 语句:int num100; float salary100; char name10025;/* 在此为ARRAY赋值 */EXEC SQL INSERT INTO
40、emp(empno,ename,sal) VALUES (:num, :name, :salary);,用数组(array)操作多行多列,用 数组(array)操作多行多列,数组和 UPDATE / DELETE 语句Char name100; float salary100;. /* 在此为ARRAY赋值 */EXEC SQL UPDATE EMP SET sal=:salary WHERE ename=:name;Char name100;. /* 在此为ARRAY赋值 */EXEC SQL DELETE FROM emp WHERE ename=:name;,用 数组(array)操作多
41、行多列,数组和 SELECT 语句Char name10025;EXEC SQL SELECT ename INTO :name FROM empWHERE dept_num=2;For(int j=0;jsqlca.sqlerrd2;j+) cout“Emp_name”namejendl;,用 数组(array)操作多行多列,注意事项:只有CHAR 和 VARCHAR 可为二维数组。如数组INDEX不同,按最小操作。在SELECT语句的WHERE子句中,不能用数组。数组元素最大值:32767,使用非滚动游标,1。定义游标 EXEC SQL DECLARE emp_cursor CURSOR
42、FOR select empno,ename,sal from emp where deptno=10; 2. 打开游标 EXEC SQL OPEN emp_cursor ; (Open cursor: put the select results into a memory place, and the cursor pointer points to the first row data.)3. 提取游标 EXEC SQL FETCH emp_cursor INTO :empnum,:name:salary; /* 在此处理数据处理*/ (After fetch, cursor point
43、er moves down one line. Use loop for multiple rows)4. EXEC SQL CLOSE emp_cursor;,使用非滚动游标范例,int dept_number, emp_name; float commission;EXEC SQL DECLARE emp_cursor CURSOR FOR SELECT empname, comm FROM EMP WHERE deptno = :dept_number;EXEC SQL OPEN emp_cursor;for( ;) EXEC SQL WHENEVER NOT FOUND DO brea
44、k;EXEC SQL FETCH emp_cursor INTO :emp_name, :commission;if(commission 1) coutemp_name“先生,请加油“; EXEC SQL CLOSE emp_cursor;,使用滚动游标,1. 定义游标 EXEC SQL DECLARE emp_cursor SCROLL CURSOR FOR select empno,ename,sal from emp where deptno=10; 2. 打开游标 EXEC SQL OPEN emp_cursor ; 3. 提取游标 EXEC SQL FETCH FIRST emp_
45、cursor INTO:empnum,:name:salary; options: PRIOR(当前行的前一行),NEXT(当前行的下一行), CURRENT(当前行),RELATIVE n (n为付/正,当前行的前/后n行) ,ABSOLUTE n (游标中的第n行), LAST。 4. EXEC SQL CLOSE emp_cursor;,动态SQL,动态SQL是指在运行pro*c/c+应用程序时,动态输入的SQL语句。目的:加强应用程序的功能和灵活性。比较静态SQL和动态SQL:静态SQL - 在编写应用程序时,使用EXEC SQL关键字直接嵌入的SQL语句;动态SQL - 在运行应用程
46、序时,由用户动态输入的SQL语句。什么时候使用动态SQL语句SQL语句的文本(命令,子句等)不确定宿主变量个数不确定宿主变量的数据类型不确定引用的数据库对象(列,表等)不确定,动态SQL1,动态SQL1概述语法:EXEC SQL EXECUTE IMMEDIATE :host_stringhost_string 字符串char sqlstmt100;Gets(sqlstmt)/* user input from keybord: “CREATE TABLE student( sno INT, sname CHAR(15) )” */EXEC SQL EXECUTE IMMEDIATE :sql
47、stmt;,动态SQL1,仅适用于非select语句语句中不包含输入宿主变量判断如下语句是否能用:Delete from emp where empno=:a;Delete from emp where empno=7788;Select ename from emp where empno=7788;常用于仅执行一次的动态语句对重复执行多次的动态SQL语句,降低执行效率,动态SQL方法2,动态SQL方法21。使用PREPARE命令准备SQL语句 EXEC SQL PREPARE statement_name FROM :host_string; statement_name: 标识符, ho
48、st_string:含SQL语句的字符串2。使用EXECUTE命令执行SQL语句 EXEC SQL EXECUTE statement_name USING :host_variable3。如果SQL语句要通过宿主变量赋值,输入SQL语句时要用占位符,动态SQL方法2示例,int emp_number;char sqlstmt1100;char emp_name20;char job20;float salary;strcpy( sqlstmt1, “INSERT INTO emp(empno, ename, job, sal) VALUES(:v1, :v2, :v3, :v4) ” );E
49、XEC SQL PREPARE S FROM :sqlstmt1;EXEC SQL EXECUTE S USING :emp_number, :emp_name, :job, :salary;,动态SQL方法2,仅适用于非select语句可包含虚拟输入宿主变量和指示器变量,其个数和类型在预编译时已知,动态SQL方法2,优点:分析一次,可用不同的实宿主变量值执行多次int emp_number, sqlstmt100, emp_name20, job20;float salary;strcpy( sqlstmt1, “INSERT INTO emp(empno, ename, job, sal)
50、 VALUES(:v1, :v2, :v3, :v4) ” );EXEC SQL PREPARE S FROM :sqlstmt1;for( i=0; i 100; i+ ) /* 赋值给 :emp_number, :emp_name, :job, :salary; */ EXEC SQL EXECUTE S USING :emp_number, :emp_name, :job, :salary;,动态SQL方法3,1. 使用PREPARE命令准备SQL语句 EXEC SQL PREPARE statement_name FROM :host_string; statement_name: 标