关于PLSQL中的一些问题总结:在PLSQL中书写DDL等
关于问题前导,使用的数据表中涉及到的字段和类型:

在PLSQL中create、drop、truncate等DDL是没有办法直接执行的。
必须要使用:
Execute immediate ‘DDL语句’
但是我发现这样并不能执行!后面查阅发现,oracle中执行DDL语句需要使用变量的形式:
即 所谓的动态SQL语句
首先在declare中声明变量( 例如:sql varchar2(200):= ‘create table tmp(name varchar2(20), age number(3))’ ),再在begin和end之间 execute immediate才可以!
DML
关于DML insert、delete、update是可以直接执行的,而且通过SQL对象会返回受到影响的行数。
但是这里需要注意的是:如果你是在同一个PLSQL中创建了表,同时想在这个PLSQL中insert数据的话,就必须要小心了!!!
也要使用:executeimmediate的方式来执行:注意,最好也是通过变量的形式执行:
直接把语句通过 executeimmediate引在后面当然可以,但是这样的话,数据就必须得写死

而且有varchar和varchar2类型的时候,就很麻烦了:
引号就会冲突;
通过变量声明的方式


就更显得灵活了!
因为execute这种形式,是加载进来的时候,就会做判断的,最开始insert的话,如果检测到表不存在!就会报错!
所以为了保证和create统一加载,忽略oracle的报错(我的理解这个和java反射类似,弱引用一样),就要统一为execute immediate
DQL
但是关于select的话,不能单独执行,除非后面有into语句,才有执行意义,才不会报错!
最后需求的是查出这样的一个表结构:

以下代码纯属PLSQL、存储过程练手:
1.创建一个传入系名进行查询平均成绩的存储过程
create or replace procedure in_dname_out_avg_grade(
i_dname in dep.dname%type,
o_agrade out number
)
as
begin
select avg(grade) agrade into o_agrade
from
(
select course.cname, dep.dname, sc.grade
from course
inner join sc on course.cno = sc.cno
inner join student on sc.sno = student.sno
inner join dep on dep.dno = student.dno
where course.cname = '大学物理' and dep.dname = i_dname
);
end;
2.创建一个传入系名查询不及格人数的存储过程
create or replace procedure in_dname_out_grade_low(
i_dname in dep.dname%type,
o_num out number
)
as
begin
select count(student.sno) into o_num
from course
inner join sc on course.cno = sc.cno
inner join student on sc.sno = student.sno
inner join dep on dep.dno = student.dno
where course.cname = '大学物理' and dep.dname = i_dname and sc.grade < 60;
end;
3.创建一个传入系名查询 60-85分人数的存储过程
create or replace procedure in_dname_out_grade_mid(
i_dname in dep.dname%type,
o_num out number
)
as
begin
select count(student.sno) into o_num
from course
inner join sc on course.cno = sc.cno
inner join student on sc.sno = student.sno
inner join dep on dep.dno = student.dno
where course.cname = '大学物理' and dep.dname = i_dname and sc.grade >=60 and sc.grade < 85;
end;
4.创建一个传入系名查询 85分以上人数的存储过程
create or replace procedure in_dname_out_grade_hig(
i_dname in dep.dname%type,
o_num out number
)
as
begin
select count(student.sno) into o_num
from course
inner join sc on course.cno = sc.cno
inner join student on sc.sno = student.sno
inner join dep on dep.dno = student.dno
where course.cname = '大学物理' and dep.dname = i_dname and sc.grade >=85;
end;
补充注意:
存储过程不能有declare声明!!!
如果要声明变量的话直接,如下:
create or replace procedure createTable_procedure
as
-- declare 存储过程不能有声明!!
v_DDL varchar2(200) :=
'create table tmp(
t_cname varchar2(20),
t_dname varchar2(20),
grade_low number,
grade_mid number,
grade_hig number,
grade_avg number
)';
begin
execute immediate v_DDL;
end;
最后得出结果表的PLSQL,注意要用到上面的存储过程:
declare
cursor dname_cursor is
select distinct dep.dname
from student
inner join sc on student.sno = sc.sno
inner join dep on dep.dno = student.dno
where sc.cno = (
select course.cno
from course
where course.cname = '大学物理'
);
type dnameContain is table of dep.dname%type
index by binary_integer;
contain dnameContain;
m_cname course.cname%type := '大学物理';
m_dname dep.dname%type;
m_low number;
m_mid number;
m_hig number;
m_avg number(3);
i number := 0;
v_DDL varchar2(200) :=
'create table tmp(
t_cname varchar2(20),
t_dname varchar2(20),
grade_low number,
grade_mid number,
grade_hig number,
grade_avg number
)';
v_DML varchar2(100) :=
'insert into tmp values(:1, :2, :3, :4, :5, :6)';
begin
execute immediate ' drop table tmp';
exception when others then
null;
-- 为什么在一个PL/SQL中不能创建表后面就用
-- dbms_utility.exec_ddl_statement(v_DDL);
execute immediate v_DDL;
-- commit;
open dname_cursor;
loop
fetch dname_cursor into contain(i);
if i>0 then
-- dbms_output.put_line(contain(i-1));
m_dname := contain(i-1);
dbms_output.put_line(m_dname);
in_dname_out_grade_low(m_dname, m_low);
in_dname_out_grade_mid(m_dname, m_mid);
in_dname_out_grade_hig(m_dname, m_hig);
in_dname_out_avg_grade(m_dname, m_avg);
dbms_output.put_line(m_mid||', '||m_hig||', '||m_avg);
-- insert into tmp values(m_cname, m_dname, m_low, m_mid, m_hig, m_avg);
execute immediate v_DML using m_cname, m_dname, m_low, m_mid, m_hig, m_avg;
end if;
i := i+1;
exit when dname_cursor%notfound;
end loop;
close dname_cursor;
commit;
end;
注意:commit在PLSQL中可以直接写的!!!
关于PLSQL中的一些问题总结:在PLSQL中书写DDL等的更多相关文章
- excel中的数据粘贴不全到plsql中,excel 粘贴后空白,Excel复制粘贴内容不全
http://zhidao.baidu.com/link?url=pHZQvfWJzI-lQjl4uP86q4GLcpYHu4o-fdjiYegJS0Cy5HEq5oz0YrUye3iHjmv5CJ3 ...
- plsql oracle client没有正确安装(plsql连接远程数据库)
plsql oracle client没有正确安装(plsql连接远程数据库) CreateTime--2018年4月23日16:55:11 Author:Marydon 1.情景再现 2.问题解 ...
- Android中自定义样式与View的构造函数中的第三个参数defStyle的意义
零.序 一.自定义Style 二.在XML中为属性声明属性值 1. 在layout中定义属性 2. 设置Style 3. 通过Theme指定 三.在运行时获取属性值 1. View的第三个构造函数的第 ...
- Asp.net中存储过程拖拽至dbml文件中,提示无法获得返回值
Asp.net中存储过程拖拽至dbml文件中,提示无法获得返回值,去属性表中设置这时候会提示你去属性表中更改返回类型. 其实存储过程返回的也是一张表,只不过有时候存储过程有点复杂或者写法不规范的话不能 ...
- 如何将Eclipse中的项目迁移到Android Studio 中
如何将Eclipse中的项目迁移到Android Studio 中 如果你之前有用Eclipse做过安卓开发,现在想要把Eclipse中的项目导入到Android Studio的环境中,那么首先要做的 ...
- 在C#代码中应用Log4Net(三)Log4Net中配置文件的解释
一个完整的配置文件的例子如下所示,这个是”在C#代码中应用Log4Net(二)”中使用的配置文件. <log4net> <!-- 错误日志类--> <logger nam ...
- ASP.NET MVC搭建项目后台UI框架—8、将View中选择的数据行中的部分数据传入到Controller中
目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...
- golang中的slice翻转存在以及map中的key判断
//slice翻转 func stringReverse(src []string){ if src == nil { panic(fmt.Errorf("the src can't be ...
- java中的反射机制在Android开发中的用处
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反 ...
- ui-router中的锚点问题(angular中的锚点问题)
angular.module('anchorScrollExample', []) .controller('ScrollController', ['$scope', '$location', '$ ...
随机推荐
- ZooKeeper 分布式锁 Curator 源码 03:可重入锁并发加锁
前言 在了解了加锁和锁重入之后,最需要了解的还是在分布式场景下或者多线程并发加锁是如何处理的? 并发加锁 先来看结果,在多线程对 /locks/lock_01 加锁时,是在后面又创建了新的临时节点. ...
- MongoDB 基础学习
1.MongoDB 概念解析 SQL术语/概念 MongoDB术语/概念 解释/说明 database database 数据库 table collection 数据库表/集合 row docume ...
- React 之 组件生命周期
React 之 组件生命周期 理解1) 组件对象从创建到死亡它会经历特定的生命周期阶段2) React组件对象包含一系列的勾子函数(生命周期回调函数), 在生命周期特定时刻回调3) 我们在定义组件时, ...
- c# 将checkedListBox选择的值保存再数组中并转换成以指定字符连接的字符串
经常忘记,所以记一下: string[] arr =new string[3]; int b = 0; foreach (string outstr in checkedListBox1.Checke ...
- java 日期字符串互相转换
一.把日期转换成字符串 //获取当前时间 Date date = new Date(); //打印date数据类型 System.out.println(date.getClass().get ...
- Python基础之tabview
以前写过界面,但是没有记录下来,以至于现在得从头学习一次,论做好笔记的重要性. 现在学习的是怎么写一个tabview出来,也就是用tkinter做一个界面切换的效果.参考链接:https://blog ...
- 构建前端第10篇之---Function.prototype.call()
张艳涛写于2020-01-25,参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/ ...
- 类加载机制+JVM调优实战+代码优化
类加载机制 Java源代码经过编译器编译成字节码之后,最终都需要加载到虚拟机之后才能运行.虚拟机把描述类的数据从 Class 文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直 ...
- Centos 7 安装mysql5.7 nginx tomcat
- Go语言常见的坑
目录 1. 可变参数是空接口类型 2. 数组是值传递 3.map遍历是顺序不固定 4. 返回值被屏蔽 5.recover必须在defer函数中运行 6. main函数提前退出 7.通过Sleep来回避 ...