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 ...
随机推荐
- IE快捷键
键盘快捷键 在后台打开新选项卡中的链接 CTRL+单击 在前台打开新选项卡中的链接 CTRL+SHIFT+单击 在前台打开新选项卡 CTRL+T 从地址栏打开新选项卡 ALT+ENTER 从搜索框打开 ...
- Chatbot中的填槽(Slot Filling)(转)
以下内容是学习了@我偏笑发布在公众号hanniman文章后,加上自己观点重新输出配图的文章 原文链接:http://t.cn/RE0FkgD 跳槽,吐槽,匹诺曹都听过,这个填槽,emmmm,黑人问号脸 ...
- css 响应式布局
移动端最让人闹心的就是在不同的手机要做错响应式布局适应各种手机,开始自己做这方面走了很多的弯路,响应式布局如果是部件,就按实际的大小单位px等设置,像宽可以按照百分比计算,长的可以百分比.auto 或 ...
- Redis原子计数器incr
一.前言在一些对高并发请求有限制的系统或者功能里,比如说秒杀活动,或者一些网站返回的当前用户过多,请稍后尝试.这些都是通过对同一时刻请求数量进行了限制,一般用作对后台系统的保护,防止系统因为过大的流量 ...
- 第七篇:Jmeter连接MySQL的测试
.准备一个有数据表格的MySQL数据库: 2.在测试计划面板上点击浏览按钮,把你的JDBC驱动添加进来: mysql-connector-java-5.1.26-bin.jar 3.添加一个线程组-- ...
- HTTPS加密过程分析
HTTPS加密的作目的是解决信息传输过程中数据被篡改,窃取 HTTPS使用了一系列的加密算法:对称加密算法.非对称加密算法.单向加密算法 非对称加密算法 分为公钥部分和私钥部分,用公钥加密的密文只能由 ...
- 使用tor网络
在www.torproject.org/projects/torbrowser.html.en上找到合适的版本下载 下载好tor浏览器之后,解压双击Tor Browser,出现这个错误 这是因为kal ...
- SIGTERM、SIGKILL、SIGINT和SIGQUIT的区别
转自:http://blog.csdn.net/dai_xiangjun/article/details/41871647 SIGQUIT 在POSIX兼容的平台,SIGQUIT是其控制终端发送到进程 ...
- 【Nodejs】ExpressのRequestとResponseの内容
Request 对象 - request 对象表示 HTTP 请求,包含了请求查询字符串,参数,内容,HTTP 头部等属性.常见属性有: req.app:当callback为外部文件时,用req.ap ...
- 191. Number of 1 Bits (Int; Bit)
Write a function that takes an unsigned integer and returns the number of ’1' bits it has (also know ...