百度糯米网站怎么做,网站页面一般以多大标准做合适,无锡网络公司服务平台,网站怎么做排查修复一、SQL的执行流程数据库中的所有SQL语句都经历了不同的阶段#xff1a;
•解析#xff1a;预执行“这可能吗#xff1f;”检查包括语法#xff0c;对象存在#xff0c;权限等
•绑定#xff1a;获取语句中引用的任何变量的实际值
•执行#xff1a;语句被执行。•提取
•解析预执行“这可能吗”检查包括语法对象存在权限等
•绑定获取语句中引用的任何变量的实际值
•执行语句被执行。•提取结果返回给用户。
某些阶段可能与所有语句无关;例如提取阶段适用于查询但不适用于DML。二、PL / SQL子程序中SQL的执行流程
当PL / SQL子程序中包含SQL语句时解析和绑定阶段通常是在编译时完成的也就是说当过程函数或包体是CREATEd时。
如果在创建过程时SQL语句的文本未知该怎么办 Oracle服务器如何解析它 它不能。 例如假设您想要删除一个表但用户在执行时输入表名
CREATE PROCEDURE drop_any_table(p_table_name VARCHAR2)
IS BEGINDROP TABLE p_table_name; -- cannot be parsed
END;三、动态SQL您使用动态SQL来创建一个SQL语句其中的文本事先不完全知道。
动态SQL
•构造并存储为子程序内的字符串。
•是否包含具有不同列数据的SQL语句或带有或不带有占位符绑定变量的不同条件。•使数据定义数据控制或会话控制语句能够从PL / SQL写入和执行。
1本地动态SQLPL / SQL不支持直接写在procedure中的DDL语句。 本地动态SQL允许您通过在子程序中构建SQL并将其存储为字符串来解决此问题。 本地动态SQL
•以PL / SQL语言直接为动态SQL提供本机支持。•使数据定义数据控制或会话控制语句能够从PL / SQL写入和执行。
•使用本机动态SQL语句EXECUTE IMMEDIATE或DBMS_SQL包执行。•提供执行直到执行时间结构未知的SQL语句的能力。
•也可以使用OPEN-FORFETCH和CLOSE PL / SQL语句。2使用EXECUTE IMMEDIATE语句
在PL / SQL匿名块或子程序中为原生动态SQL使用EXECUTE IMMEDIATE语句
EXECUTE IMMEDIATE dynamic_string
[INTO {define_variable[, define_variable] ... | record}]
[USING [IN|OUT|IN OUT] bind_argument[, [IN|OUT|IN OUT] bind_argument] ... ];•INTO用于单行查询并指定检索列值的变量或记录。•USING保存所有绑定参数。 如果未指定则默认参数模式为IN。
•dynamic_string是包含SQL语句文本的字符变量或文字。•define_variable是一个PL / SQL变量用于存储选定的列值。•record是存储选定行的用户定义或ROWTYPE记录。
•bind_argument是一个表达式其值在执行时传递给动态SQL语句。
•USING子句保存所有绑定参数。 默认参数模式是IN。
示例1使用DDL语句的动态SQL
在线构建动态声明
CREATE PROCEDURE drop_any_table(p_table_name VARCHAR2) IS
BEGINEXECUTE IMMEDIATE DROP TABLE ||p_table_name;
END;在一个变量中构造动态语句
CREATE PROCEDURE drop_any_table(p_table_name VARCHAR2) ISv_dynamic_stmt VARCHAR2(50);
BEGINv_dynamic_stmt : DROP TABLE ||p_table_name;EXECUTE IMMEDIATE v_dynamic_stmt;
END;
BEGINdrop_any_table(EMPLOYEE_NAMES);
END;示例2使用DML语句的动态SQL删除任何表中的所有行并返回计数
CREATE FUNCTION del_rows(p_table_name VARCHAR2)
RETURN NUMBER IS
BEGINEXECUTE IMMEDIATE DELETE FROM ||p_table_name;RETURN SQL%ROWCOUNT;
END;
调用该函数
DECLAREv_count NUMBER;
BEGINv_count : del_rows(EMPLOYEE_NAMES);DBMS_OUTPUT.PUT_LINE(v_count|| rows deleted.);
END;示例3使用DML语句的动态SQL这是一个将行插入两列并调用过程的示例。
CREATE PROCEDURE add_row(p_table_name VARCHAR2,p_id NUMBER, p_name VARCHAR2) IS
BEGINEXECUTE IMMEDIATE INSERT INTO ||p_table_name|| VALUES (p_id, p_name);
END;
BEGIN
add_row(EMPLOYEE_NAMES, 250, Chang);
END;示例4使用本机动态SQL重新编译PL / SQL代码您可以使用下列ALTER语句重新编译PL / SQL对象而不重新创建它们
ALTER PROCEDURE procedure-name COMPILE;
ALTER FUNCTION function-name COMPILE;
ALTER PACKAGE package_name COMPILE SPECIFICATION;
ALTER PACKAGE package-name COMPILE BODY;
本示例创建一个过程用于重新编译在运行时输入其名称和类型的PL / SQL对象。
CREATE PROCEDURE compile_plsql
(p_name VARCHAR2,p_type VARCHAR2,p_options VARCHAR2 : NULL) ISv_stmt VARCHAR2(200);
BEGINv_stmt : ALTER ||p_type|| ||p_name|| COMPILE|| ||p_options;EXECUTE IMMEDIATE v_stmt;
END;
BEGIN compile_plsql(MYPACK,PACKAGE,BODY); END;四、使用DBMS_SQL包1DBMS_SQL包的一些过程和功能是• OPEN_CURSOR
• PARSE
• BIND_VARIABLE
• EXECUTE
• FETCH_ROWS
• CLOSE_CURSOR2使用带有DML语句的DBMS_SQL
删除行的示例
CREATE OR REPLACE FUNCTION del_rows
(p_table_name VARCHAR2) RETURN NUMBER ISv_csr_id INTEGER;v_rows_del NUMBER;
BEGINv_csr_id : DBMS_SQL.OPEN_CURSOR;DBMS_SQL.PARSE(v_csr_id,DELETE FROM ||p_table_name, DBMS_SQL.NATIVE);v_rows_del : DBMS_SQL.EXECUTE (v_csr_id);DBMS_SQL.CLOSE_CURSOR(v_csr_id);RETURN v_rows_del;
END;
请将本文前面的内容与del_rows函数进行比较。 它们功能相同但更简单3使用带有参数化DML语句的DBMS_SQL再次将其与本课前面的add_row过程进行比较。 你宁愿写什么CREATE PROCEDURE add_row (p_table_name VARCHAR2,
p_id NUMBER, p_name VARCHAR2) ISv_csr_id INTEGER;v_stmt VARCHAR2(200);v_rows_added NUMBER;
BEGINv_stmt : INSERT INTO ||p_table_name|| VALUES (||p_id||,||p_name||);v_csr_id : DBMS_SQL.OPEN_CURSOR;DBMS_SQL.PARSE(v_csr_id,v_stmt, DBMS_SQL.NATIVE);v_rows_added : DBMS_SQL.EXECUTE(v_csr_id);DBMS_SQL.CLOSE_CURSOR(v_csr_id);
END;五、本地动态SQL与DBMS_SQL包的比较
原生动态SQL
•比DBMS_SQL更易于使用•比DBMS_SQL需要更少的代码
•通常执行速度比DBMS_SQL快因为执行的语句较少。