Oracle_PL/SQL(8) 动态sql
动态sql
0.pl/sql块的限制
不能执行ddl操作(create、drop、alter);
不能执行部分dcl操作(grant、revoke)。
1.语法
动态sql:在执行时才能确定要执行的sql语句。
在pl/sql块中编写动态sql语句时,需要将sql语句存放到字符串变量中,
而且sql可以包含占位符。
execute immediate dynamic_string
dynamic_string :是存放要被执行的sql语句的字符串变量。
2.用途
可处理:
ddl语句(create,alter,drop),
dcl语句(grant,revoke),
dml语句(insert,update,delete)
单行select语句
多行select语句需要和游标联合使用。
3.ddl操作
execute immediate后面只需要带有ddl语句
create or replace procedure drop_table(table_name varchar2)
is
sql_statement varchar2(100);
begin
sql_statement:='drop table '||table_name;
execute immediate sql_statement;
end;
/
exec drop_table('emp_log');
4.dcl操作(grant、revoke)
conn sys/123 as sysdba;
create or replace procedure grant_sys_priv(priv varchar2,username varchar2)
is
sql_stat varchar2(100);
begin
sql_stat:='grant '||priv||' to '||username;
execute immediate sql_stat;
end;
/
--授权前检查
select * from user_sys_privs;
--授权
exec grant_sys_priv('create any table','scott')
--grant create any view,drop any view to scott;
create or replace procedure revoke_sys_priv(priv varchar2,username varchar2)
is
sql_stat varchar2(100);
begin
sql_stat:='revoke '||priv||' from '||username;
execute immediate sql_stat;
end;
/
5.dml操作
5.1 sql语句不需要参数
declare
sql_stat varchar2(100);
begin
--update emp set sal=sal*1.1 where deptno=30;
sql_stat:='update emp set sal=sal*1.1 where deptno=30';
execute immediate sql_stat;
end;
5.2 sql语句需要参数
: 占位符--》绑定变量
using 传递参数
& 从客户端接收参数
declare
sql_stat varchar2(100);
begin
sql_stat:='update emp set sal=sal*(1+:percent/100) where deptno=:dno';
execute immediate sql_stat using &percent,&dno;
end;
改造:
create or replace procedure proc_emp_addsal(p_dno number,p_percent number)
is
begin
update emp set sal=sal*(1+p_percent/100) where deptno=p_dno;
end;
6.单行select语句
需要使用into子句接受返回数据
语法:
execute immediate dynamic_string
[into (define_variable|record)]
[using bind_argument]
declare
sql_stat varchar2(100);
v_ename emp.ename%type;
begin
sql_stat:='select ename from emp where empno=:enp';
execute immediate sql_stat into v_ename using &enp;
dbms_output.put_line('雇员:'||v_ename);
end;
改造:
create or replace function func_emp_ename(p_empno number) return varchar2
is
v_ename emp.ename%type;
begin
select ename into v_ename from emp where empno=p_empno;
return v_ename;
end;
7.多行select语句
7.1 使用游标
为了处理动态的多行查询操作,必须要使用open-for语句打开游标,
使用fetch循环提取数据,close关闭游标
declare
type empcurtyp is ref cursor;
emp_cv empcurtyp;
emp_record emp%rowtype;
sql_stat varchar2(100);
begin
sql_stat:='select * from emp where deptno=:dno';
open emp_cv for sql_stat using &dno;
loop
fetch emp_cv into emp_record;
exit when emp_cv%notfound;
dbms_output.put_line('雇员名:'||emp_record.ename||',工资:'||emp_record.sal);
end loop;
close emp_cv;
end;
7.2 bulk collect into 集合
bulk collect批量操作
declare
type ename_table_type is table of emp%rowtype;
ename_table ename_table_type;
sql_stat varchar2(100);
begin
sql_stat:='select * from emp where deptno=:dno';
execute immediate sql_stat bulk collect into ename_table using &dno;
for i in 1..ename_table.count loop
dbms_output.put_line('雇员名:'||ename_table(i).ename||',工资:'||ename_table(i).sal);
end loop;
end;
改造:
create or replace procedure proc_emp_enamesal(p_dno number)
is
begin
for rs in (select * from emp where deptno=p_dno) loop
dbms_output.put_line('雇员名:'||rs.ename||',工资:'||rs.sal);
end loop;
end;
/
exec proc_emp_enamesal(20);
8.实际工作中的用途
8.1 对于分表处理
create or replace procedure proc_stu (p_tab varchar2,p_id number)
is
type ename_table_type is table of stu_oracle%rowtype;
ename_table ename_table_type;
sql_stat varchar2(100);
begin
sql_stat:='select * from '||p_tab||' where id='||p_id;
execute immediate sql_stat bulk collect into ename_table;
for i in 1..ename_table.count loop
dbms_output.put_line('学生名:'||ename_table(i).sname);
end loop;
end;
/
show err;
begin
proc_stu('stu_java',11);
end;
8.2 对拼接函数通用功能的实现
create or replace function func_concat(p_expectfield varchar2,
p_expecttable varchar2,p_expectcause varchar2) return varchar2
is
/*
函数功能:获取单个属性将其拼成一行
参数说明:p_expectfield 查询字段
p_expecttable 查询主表
p_expectcause 查询条件
*/
v_sql varchar2(4000):='';
type type_cursor is ref cursor;
v_cur type_cursor;
v_per varchar2(4000):='';
v_cnt number:=0;
v_return varchar2(4000):='';
begin
v_sql:='select '||p_expectfield||' from '||p_expecttable||' where '||p_expectcause;
open v_cur for v_sql;
loop
fetch v_cur into v_per;
exit when v_cur%notfound;
if v_cnt=0 then
v_return:=v_per;
else
v_return:=v_return||','||v_per;
end if;
v_cnt:=v_cnt+1;
end loop;
close v_cur;
return v_return;
end func_concat;
/
show err;
select func_concat('ename','emp','1=1') from dual;
select func_concat('distinct job','emp','deptno=20') from dual;
select func_concat('dname','dept','1=1') from dual;
--select ename from emp,dept where emp.deptno=dept.deptno and dept.deptno=20;
select func_concat('ename','emp,dept','emp.deptno=dept.deptno and dept.deptno=20') from dual;
--select job from emp where ename='scott1';
select func_concat('job','emp','ename=''scott1''') from dual;
--select ename from emp,dept where emp.deptno=dept.deptno and lower(dname)='sales';
select func_concat('ename','emp,dept','emp.deptno=dept.deptno and lower(dname)=''sales''') from dual;
作业:
1.用动态sql创建表,给表增加列、删除列、修改列长度;
2.用动态sql创建表,给表增加主键约束、唯一键约束、外键约束;
3.用动态sql截断表;
4.用动态sql实现部门表的Insert、Delete功能
Oracle_PL/SQL(8) 动态sql的更多相关文章
- (转)[SQL Server] 动态sql给变量赋值(或返回值给变量)
本文转载自:http://blog.csdn.net/xiaoxu0123/article/details/5684680 [SQL Server] 动态sql给变量赋值(或返回值给变量) decla ...
- 动态SQL是什么??什么是静态SQL,动态SQL的动态体现在哪里???
首先,所谓SQL的动态和静态,是指SQL语句在何时被编译和执行,二者都是用在SQL嵌入式编程中的,这里所说的嵌入式是指将SQL语句嵌入在高级语言中,而不是针对于单片机的那种嵌入式编程.在某种高级语言中 ...
- 第15讲:嵌入式SQL语句(动态SQL)
一.动态SQL概述 1. 静态SQL vs 动态SQL ①动态SQL是相对静态SQL而言的 ②静态SQL特点:SQL语句在程序中已经按要求写好,只需要把一些参数通过变量传递给SQL语句即可 specN ...
- SQL Server ——动态SQL
EXECUTE 执行 Transact-SQL 批中的命令字符串.字符串或执行下列模块之一:系统存储过程.用户定义存储过程.标量值用户定义函数或扩展存储过程.SQL Server 2005 扩展了 E ...
- 关于注解sql和动态sql的写法
注解写sql一般写在mapper层,如果sql语句复杂建议不要写注解sql 拼接容易出错 二动态sql的话要在 main 下面创建一个resource ——mapper—— Mapper.xml 再在 ...
- pl/sql执行动态sql
SQL> declare msql varchar2(200); begin loop msql := 'select * from bfw_test' ...
- Mysql - 游标/动态sql/事务
游标这个在我目前的项目里面用的还不多, 但是其功能还是很强大的. 动态sql以前都没用过, 是跟着富士康(不是张全蛋的富土康哦)过来的同事学的. 还是挺好用的. 我的数据库方面, 跟他学了不少. 在此 ...
- 动态SQL语句之sp_executesql的使用
sp_executesql,sql2005中引入的新的系统存储过程,也是用来处理动态sql的, 如: exec sp_executesql @sql, N'@item_name nvarchar(10 ...
- Oracle基础 动态SQL语句
一.静态SQL和动态SQL的概念. 1.静态SQL 静态SQL是我们常用的使用SQL语句的方式,就是编写PL/SQL时,SQL语句已经编写好了.因为静态SQL是在编写程序时就确定了,我们只能使用SQL ...
随机推荐
- EF 踩过的坑
ef + mysql-8.0.12-winx64 这个版本的mysql,当一个类为树型结构,会迁移报错. 数据迁移提示:No connection string named 'TaoBaoEntiti ...
- Linux下Shell命令加减乘除计算
使用 expr命令 (其中做乘的时候*号要用斜杠进行转义) 除以 [hadoop-user@hadoop1]$ echo `expr 9 / 3` 3加 [hadoop-use ...
- kibana test
https://www.cnblogs.com/yiwangzhibujian/p/7137546.html curl -XPUT http://localhost:9200/shakespeare ...
- 2.1、CDH 搭建Hadoop在安装(为Cloudera Manager配置存储库)
步骤1:为Cloudera Manager配置存储库 使用包管理工具安装Cloudera Manager yum 对于RHEL兼容系统, zypper对于SLES,和 apt-get对于Ubuntu. ...
- Java KeyNote
[Java KeyNote] 1.把一个ArrayList拷贝到另一个ArrayList. ArrayList list1=new ArrayList(); ArrayList list2=new A ...
- spark基本组件与概念
数据结构 核心之数据集RDD 俗称为弹性分布式数据集.Resilient Distributed Datasets,意为容错的.并行的数据结构,可以让用户显式地将数据存储到磁盘和内存中,并能控制数据的 ...
- 一、Blender/Python 快速入门
原文:https://docs.blender.org/api/blender_python_api_current/info_quickstart.html#native-types 1 前言 可以 ...
- jpa orderby
return criteriaQuery.where(in).orderBy(new OrderImpl(root.get("field1"))).getRestriction() ...
- pycharm的安装(图文)
pycharm的安装, PyCharm是一种 IDE,可以在里面对python代码调试.语法高亮.Project管理.跳转.智能提示.自动完成.单元测试.版本控制.pycharm提供了一些高级功能,以 ...
- python 读取文件第一列 空格隔开的数据
file=open('6230hand.log','r') result=list() for c in file.readlines(): c_array=c.split(" " ...