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 ...
随机推荐
- Django使用自定义的authentication登录认证
import ldap class LDAPMgmt(): def __init__(self): self.ldap_host = 'xxx' self.ldap_base_dn = 'ou=xx, ...
- (Unity4.7)assetbundle 坑爹总结
使用版本Unity4.7 一.关于依赖打包 1.当一个被打包的资源A引用了其他的资源B,并且没有被打成一个包时,要选用[BuildAssetBundleOptions.CollectDependenc ...
- hasattr() getattr() setattr() 函数使用方法
1. hasattr(object, name) 判断object对象中是否存在name属性,当然对于python的对象而言,属性包含变量和方法:有则返回True,没有则返回False:需要注意的是n ...
- 学JS的心路历程 -函式(三)this
this是什么,取决于被呼叫的呼叫地点. 昨天有提到说,呼叫函式时候会传递隐含参数:arguments和this并讲解了arguments,今天我们就来探讨this吧! 什么是this 我们都会呼叫函 ...
- tf.identity 个人理解
tf.identity is useful when you want to explicitly transport tensor between devices (like, from GPU t ...
- windows 激活venv问题
.\ven\Scripts\activate.\ven\Scripts\activate : 无法加载文件 D:\github\ven\Scripts\activate.ps1,因为在此系统上禁止运行 ...
- JavaScript Drag处理
[JavaScript Drag处理] 在拖动目标上触发事件 (源元素): ondragstart - 用户开始拖动元素时触发 ondrag - 元素正在拖动时触发 ondragend - 用户完成元 ...
- git查看某个文件修改历史
[git查看某个文件修改历史] 1.使用git命令 git whatchanged charge.lua 显示某个文件的每个版本提交信息:提交日期,提交人员,版本号,提交备注(没有修改细节) git ...
- Hibernate一对多关联映射的配置及其级联删除问题
首先举一个简单的一对多双向关联的配置: 一的一端:QuestionType类 package com.exam.entity; import java.util.Set; public class Q ...
- 安装 Laravel 遇到问题?你需要更新 composer.json 文件
转载自 https://9iphp.com/web/laravel/laravel-install-fail-update-composer.html 在使用最新版 Composer 安装 Larav ...