关于问题前导,使用的数据表中涉及到的字段和类型:

在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等的更多相关文章

  1. excel中的数据粘贴不全到plsql中,excel 粘贴后空白,Excel复制粘贴内容不全

    http://zhidao.baidu.com/link?url=pHZQvfWJzI-lQjl4uP86q4GLcpYHu4o-fdjiYegJS0Cy5HEq5oz0YrUye3iHjmv5CJ3 ...

  2. plsql oracle client没有正确安装(plsql连接远程数据库)

      plsql oracle client没有正确安装(plsql连接远程数据库) CreateTime--2018年4月23日16:55:11 Author:Marydon 1.情景再现 2.问题解 ...

  3. Android中自定义样式与View的构造函数中的第三个参数defStyle的意义

    零.序 一.自定义Style 二.在XML中为属性声明属性值 1. 在layout中定义属性 2. 设置Style 3. 通过Theme指定 三.在运行时获取属性值 1. View的第三个构造函数的第 ...

  4. Asp.net中存储过程拖拽至dbml文件中,提示无法获得返回值

    Asp.net中存储过程拖拽至dbml文件中,提示无法获得返回值,去属性表中设置这时候会提示你去属性表中更改返回类型. 其实存储过程返回的也是一张表,只不过有时候存储过程有点复杂或者写法不规范的话不能 ...

  5. 如何将Eclipse中的项目迁移到Android Studio 中

    如何将Eclipse中的项目迁移到Android Studio 中 如果你之前有用Eclipse做过安卓开发,现在想要把Eclipse中的项目导入到Android Studio的环境中,那么首先要做的 ...

  6. 在C#代码中应用Log4Net(三)Log4Net中配置文件的解释

    一个完整的配置文件的例子如下所示,这个是”在C#代码中应用Log4Net(二)”中使用的配置文件. <log4net> <!-- 错误日志类--> <logger nam ...

  7. ASP.NET MVC搭建项目后台UI框架—8、将View中选择的数据行中的部分数据传入到Controller中

    目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...

  8. golang中的slice翻转存在以及map中的key判断

    //slice翻转 func stringReverse(src []string){ if src == nil { panic(fmt.Errorf("the src can't be ...

  9. java中的反射机制在Android开发中的用处

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反 ...

  10. ui-router中的锚点问题(angular中的锚点问题)

    angular.module('anchorScrollExample', []) .controller('ScrollController', ['$scope', '$location', '$ ...

随机推荐

  1. Map集合笔记

    一.Map集合的特点 Map集合是一个双列集合 Map中的元素,key和value的数据类型可以相同,也可以不同. Map中的元素,key是允许重复的,value是可以重复的 Map中的元素,key和 ...

  2. spring的属性注入和构造器注入

    spring在向IOC容器中注入Bean的时候,有三种注入方式: 属性注入构造器注入工厂方法注入平常中用到的前两种方法较多,下面对前两种方法举例.一.属性注入1.创建一个car类,作为注入的bean ...

  3. Ory Kratos 用户认证

    Ory Kratos 为用户认证与管理系统.本文将动手实现浏览器(React+AntD)的完整流程,实际了解下它的 API . 代码: https://github.com/ikuokuo/start ...

  4. 使用java AWT做一个增加按钮的简单菜单窗体

    package com.ysq.Swing; import java.awt.BorderLayout; import java.awt.Container; import java.awt.Flow ...

  5. Python - 解包的各种骚操作

    为什么要讲解包 因为我觉得解包是 Python 的一大特性,大大提升了编程的效率,而且适用性很广 啥是解包 个人通俗理解:解开包袱,拿出东西 正确理解:将元素从可迭代对象中一个个取出来 python ...

  6. 外网远程顶级域名连接群晖的WebDAV文件服务映射盘符

       外网远程顶级域名连接群晖的WebDAV文件服务映射盘符 https://www.cnblogs.com/delphixx/p/11846546.html 电子文件管理规范   1.手机拍照截屏 ...

  7. 修改Eureka的metadata脚本

    最近研究了一下Spring Cloud的灰度发布, 发现方法真是多. 这里先提供一个修改Eureka注册中心里的instance实例的metadata的脚本, 可以方便地用来测试效果. 使用举例: s ...

  8. 遥远的国度 (树链剖分换根),洛谷P3979

    析:显然,若没有换根操作,则为树链剖分板子题,但是这道题我们考虑换根操作 考虑这样一个性质:在一棵树上,两点的距离路径是唯一的!! 也就是说,我们在修改路径上的点权时,不必考虑根在哪里,直接利用模板修 ...

  9. Python的round()函数与数学的四舍五入的区别

    print(round(0.5))>>0print(round(1.5))>>2print(round(2.5))>>2整数部分为偶 小数为0.5 向下取整 0也是 ...

  10. NDIS LWF:NdisFSendNetBufferLists蓝屏(DRIVER_IRQL_NOT_EQUAL_OR_LESS)

    调用NdisFSendNetBufferLists发送自定义数据包后蓝屏,蓝屏代码为DRIVER_IRQL_NOT_EQUAL_OR_LESS,如果创建的NBL都没问题,一定要确保该自定义的NBL要在 ...