3.05-7 dynamic SQL(动态SQL) Introduction 应用程序嵌入的$QL完全固定不方便:因分析方面的 意图,指定一些操作条件,有时是必要的。 所以嵌入式SQL中,提供了动态结构$QL语句的功能。 目前SQL标准和大部DBMS均增加了动态SQL功能。 动态SQL分三种类型: execute immediate SQL直接执行SQL SQL with Dynamic parameter带动态参数的SQL Query Dynamic SQL查询类动态SQL
3.05-7 dynamic SQL (动态SQL) 一 Introduction 应用程序嵌入的SQL完全固定不方便:因分析方面的 意图,指定一些操作条件,有时是必要的。 所以嵌入式SQL中,提供了动态结构SQL语句的功能。 目前SQL标准和大部DBMS均增加了动态SQL功能。 动态SQL分三种类型: execute immediate SQL 直接执行SQL SQL with Dynamic parameter 带动态参数的SQL Query Dynamic SQL 查询类动态SQL
二Dynamic SQL executed immediately (直接执行的动态SQL) ●只用于非查询语句:DDL,DM心 应用程序定义一个字符串类型的宿主变量,存 放要执行的$QL语句。 SQL语句固定部分由程序赋值给宿主变量。 可变部分由程序提示,用户输入。 用EXEC SQL EXECUTE IMMEDI ATE语句执行宿主 变量中的SQL语句
二 Dynamic SQL executed immediately (直接执行的动态SQL) ⚫ 只用于非查询语句:DDL,DML ⚫ 应用程序定义一个字符串类型的宿主变量,存 放要执行的SQL语句。 ⚫ SQL语句固定部分由程序赋值给宿主变量。 可变部分由程序提示,用户输入。 ⚫ 用EXEC SQL EXECUTE IMMEDIATE语句执行宿主 变量中的SQL语句
例:从关系STUDENT中删除指定条件的学生记 录。条件存在应用程序变量cond中.由于 cond在语句末尾,其后应加‘;’号 EXEC SQL BEGIN DECLARE SECTION; char Sqlstring[200];/*定义宿主变量*/ EXEC SQL END DECLARE SECTION; /开始行和结束行均为独立语句*/
例:从关系STUDENT中删除指定条件的学生记 录。条件存在应用程序变量cond中. 由于 cond在语句末尾,其后应加‘ ; ’号 · · · EXEC SQL BEGIN DECLARE SECTION; char Sqlstring[200]; /*定义宿主变量*/ EXEC SQL END DECLARE SECTION; /*开始行和结束行均为独立语句*/
char cond [150] /*填入SQL固定部分*/ strcopy (sqlstring,"DELETE FROM STUDENT WHERE ") printf ("Enter Search condition:" scanf ("%s,cond) strcat (sqlstr ing,cond) EXEC SQL EXECUTE IMMEDIATE sqlstr ing;
char cond[150]; /*填入SQL固定部分*/ strcopy(sqlstring,"DELETE FROM STUDENT WHERE "); printf("Enter Search condition:"); scanf("%s,cond); strcat(sqlstring,cond); EXEC SQL EXECUTE IMMEDIATE :sqlstring; · · ·
三带动态参数的动态SQL: ●也只用于非查询语句。 ● 占位器(place holder) 它是一种未定义变量,执行前应用程序提示用 户输入参数,取代占位变量。 ● 仍用删除符合条件的学生的例子。 EXEC SQL BEGIN DECLARE SECTION; Char Sqlstring [200]; int birth-year; EXEC SQL END DECLARE SECTION;
三 带动态参数的动态SQL: ⚫ 也只用于非查询语句。 ⚫ 占位器(place holder) 它是一种未定义变量,执行前应用程序提示用 户输入参数,取代占位变量。 ⚫ 仍用删除符合条件的学生的例子。 EXEC SQL BEGIN DECLARE SECTION; Char Sqlstring[200]; int birth-year; EXEC SQL END DECLARE SECTION;
Strcpy (sqlstring,"DELETE FROM STUDENT WHERE YEAR(BDATE)<=y;" Printf ("Enter birth year for deleting:") scanf ("%d",birth-year) /*用PREPRE语句定义sqlstring中SQL语句为命令 PURGE*/ EXEC SQL PREPARE PURGE FROM sqlstring; /*用birth-year取代y,并执行PURGE*/ EXEC SQL EXECUTE PURGE USING birth-ye
Strcpy (sqlstring,"DELETE FROM STUDENT WHERE YEAR(BDATE)<= :y;") Printf ("Enter birth year for deleting:"); scanf("%d",birth-year); /*用PREPRE语句定义sqlstring中SQL语句为命令 PURGE*/ EXEC SQL PREPARE PURGE FROM :sqlstring; /*用birth-year取代y,并执行PURGE*/ EXEC SQL EXECUTE PURGE USING :birth-year; · · ·
上例中: ●y没有说明, place holder占位器 ●执行中将用户输入的birth-year值取代它。 动态$QL语句中可有多个占位变量,这时 USNG后为宿主变量列表,占位变量依据在语 句中出现先后,从前向后使用USING后的宿主 变量去代
上例中: ⚫ y没有说明, place holder占位器 ⚫ 执行中将用户输入的birth-year值取代它。 ⚫ 动态SQL语句中可有多个占位变量,这时 USING后为宿主变量列表,占位变量依据在语 句中出现先后,从前向后使用USING后的宿主 变量去代
查询类动态$QL: 查询类动态$QL必须返回查询结果。且结果 为一个元组,还是多元组不能在编程时确定。 故动态查询类$QL一律用游标取数。 下边例子,用户输入ORDER BY子句和课号。 ORDER BY子句在语句尾,注意其后必须加 分号。 如需要,整个SQL语句也可动态构成,这给 动态$QL增加了交互能力,有时是很有用处 的
四 查询类动态SQL: ⚫ 查询类动态SQL必须返回查询结果。且结果 为一个元组,还是多元组不能在编程时确定。 故动态查询类SQL一律用游标取数。 ⚫ 下边例子,用户输入ORDER BY子句和课号。 ⚫ ORDER BY 子句在语句尾,注意其后必须加 分号。 ⚫ 如需要,整个SQL语句也可动态构成,这给 动态SQL增加了交互能力,有时是很有用处 的
EXEC SQL BEGIN DECLARE SECTION; char sqlstring [200] char SNO[7]; float GRADE; short GRADEl char GIVENCNO [6] EXEC SQL END DECLAR SECTION; char orderby [150]; strcpy (sql str ing,"SELECT SNO,GRADE FROM SC WHERE CNO=c");
EXEC SQL BEGIN DECLARE SECTION; char sqlstring[200]; char SNO[7]; float GRADE; short GRADEI char GIVENCNO[6]; EXEC SQL END DECLAR SECTION; char orderby[150]; strcpy(sqlstring,"SELECT SNO,GRADE FROM SC WHERE CNO= :c");
/*提示用户输入ORDER BY-子句*/ printf("Enter the ORDER BY clause:") scanf ("%s",orderby) strcat (sql string,orderby) /*提示用户输入要查询的课号*/ printf (Enter the course number:" scanf ("%s",GI VENCNO) EXEC SQL PREPARE query FROM sqlstring; /*声明游标*/ EXEC SQL DECLARE grade-cursor CURSOR FOR query; /*打开游标,取代战位器,执行相应$QL语句*/ EXEC SQL OPEN grade-cursor USING GIVENCNO;
/*提示用户输入ORDER BY子句*/ printf("Enter the ORDER BY clause:"); scanf("%s", orderby); strcat(sqlstring,orderby); /*提示用户输入要查询的课号*/ printf(Enter the course number:"); scanf("%s",GIVENCNO); EXEC SQL PREPARE query FROM :sqlstring; /*声明游标*/ EXEC SQL DECLARE grade-cursor CURSOR FOR query; /*打开游标,取代战位器,执行相应SQL语句*/ EXEC SQL OPEN grade-cursor USING :GIVENCNO;