动态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的更多相关文章

  1. (转)[SQL Server] 动态sql给变量赋值(或返回值给变量)

    本文转载自:http://blog.csdn.net/xiaoxu0123/article/details/5684680 [SQL Server] 动态sql给变量赋值(或返回值给变量) decla ...

  2. 动态SQL是什么??什么是静态SQL,动态SQL的动态体现在哪里???

    首先,所谓SQL的动态和静态,是指SQL语句在何时被编译和执行,二者都是用在SQL嵌入式编程中的,这里所说的嵌入式是指将SQL语句嵌入在高级语言中,而不是针对于单片机的那种嵌入式编程.在某种高级语言中 ...

  3. 第15讲:嵌入式SQL语句(动态SQL)

    一.动态SQL概述 1. 静态SQL vs 动态SQL ①动态SQL是相对静态SQL而言的 ②静态SQL特点:SQL语句在程序中已经按要求写好,只需要把一些参数通过变量传递给SQL语句即可 specN ...

  4. SQL Server ——动态SQL

    EXECUTE 执行 Transact-SQL 批中的命令字符串.字符串或执行下列模块之一:系统存储过程.用户定义存储过程.标量值用户定义函数或扩展存储过程.SQL Server 2005 扩展了 E ...

  5. 关于注解sql和动态sql的写法

    注解写sql一般写在mapper层,如果sql语句复杂建议不要写注解sql 拼接容易出错 二动态sql的话要在 main 下面创建一个resource ——mapper—— Mapper.xml 再在 ...

  6. pl/sql执行动态sql

    SQL> declare             msql varchar2(200);    begin    loop    msql := 'select * from bfw_test' ...

  7. Mysql - 游标/动态sql/事务

    游标这个在我目前的项目里面用的还不多, 但是其功能还是很强大的. 动态sql以前都没用过, 是跟着富士康(不是张全蛋的富土康哦)过来的同事学的. 还是挺好用的. 我的数据库方面, 跟他学了不少. 在此 ...

  8. 动态SQL语句之sp_executesql的使用

    sp_executesql,sql2005中引入的新的系统存储过程,也是用来处理动态sql的, 如: exec sp_executesql @sql, N'@item_name nvarchar(10 ...

  9. Oracle基础 动态SQL语句

    一.静态SQL和动态SQL的概念. 1.静态SQL 静态SQL是我们常用的使用SQL语句的方式,就是编写PL/SQL时,SQL语句已经编写好了.因为静态SQL是在编写程序时就确定了,我们只能使用SQL ...

随机推荐

  1. Android DevArt5:如何在Android中创建多线程?

    本篇内容: 如何在Android中创建多进程?查看进程的三种方式有哪些? 多进程模式的运行机制?- 演示了多进程出现问题中的两种情况: 静态成员失效 Application多次创建 IPC基础概念介绍 ...

  2. 23.网络.md

    目录 1.基本概念 2.常用函数 3.端口 4.协议 4.1.2代码步骤 4.1.3UDPDemo 4.1.4通信格式 4.1.5 群发Demo: 4.1.6丢失数据的情况 4.2TCP 4.2.1三 ...

  3. Java调用C/C++实现的DLL动态库——JNI

    由于项目的需要,最近研究了java 调用DLL的方法,将如何调用的写于此,便于日后查阅: 采用的方法是JNI:Java Native Interface,简称JNI,是Java平台的一部分,可用于让J ...

  4. 微信小程序-获取当前城市位置及再次授权地理位置

    微信小程序-获取当前城市位置 1. 获取当前地理位置,可通过wx.getLocation接口,返回经纬度.速度等信息; 注意---它的默认工作机制: 首次进入页面,调用该api,返回用户授权结果,并保 ...

  5. Spring Boot Maven 打包 Jar

    Maven pom.xml 必须包含 <packaging>jar</packaging> <build> <plugins> <plugin&g ...

  6. zabbix 利用python脚本实现钉钉告警

    Zabbix 利用python脚本实现钉钉告警 1.安装python3.6环境 2.创建python脚本 cd local/zabbix-4.0.3/share/zabbix/alertscripts ...

  7. node-pre-gyp install --fallback-to-build 错误

    [node-pre-gyp install --fallback-to-build 错误] npm install bcrypt时遇上错误 此时,安装node-gyp npm install -g n ...

  8. CircleImageView of Android

    [CircleImageView of Android] github上有一个开源的圆角图片项目.地址:https://github.com/hdodenhof/CircleImageView 使用分 ...

  9. 安卓自动生成代码插件-Android code Generator(转)

    编辑推荐:稀土掘金,这是一个针对技术开发者的一个应用,你可以在掘金上获取最新最优质的技术干货,不仅仅是Android知识.前端.后端以至于产品和设计都有涉猎,想成为全栈工程师的朋友不要错过! 介绍 A ...

  10. redis主从复制踩到的那些坑

    一.报错:* MASTER <-> SLAVE sync started # Error condition on socket for SYNC: No route to host解决: ...