2015.1.15 利用Oracle函数返回表结果 重大技术进步!
-- sql 调用 select * from table( get_airway_subpoint(x,x,x))
/////////////////////////////////////////////////////////////////////
方法一、用游标实现,SLM提供,没有后面的方案二好,可以不用游标,更简单的方案2
//////////////////////////////////////////////////////////////////////
create or replace function subairway(pid1 in number,
awid in number,
pid2 in number) return tab_pnt is
--函数功能是返回awid航路两点间的所有航路点
type mycursor is ref cursor; --定义游标类型
dr row_pnt := row_pnt(0, 0, null); --type 行类型每条点记录 create or replace type row_pnt is object(srt number(5),pid number(11),pnm varchar2(50))
dt tab_pnt:= tab_pnt(); --type 表类型,返回航路所有点 create or replace type tab_pnt as table of row_pnt
dtt tab_pnt:= tab_pnt(); --结果表,两点之间的所有表记录
-- 表类型和行类型必须先初始化,否则编译不错但运行会提示错误
cur_pnt mycursor; -- 游标
n1 number(5); --两点在航路走向中的序号
n2 number (5);
tm number(5);
begin
open cur_pnt for --游标可看做一张结果表
select st,pid,pnm from (
select f1.code_sort st,f2.airway_point1 pid,f3.txt_name || decode(f3.tab, 'DES', '', f3.tab) pnm
from rte_seg f1, segment f2, airway_point f3
where f1.segment_id = f2.segment_id
and f2.airway_point1 = f3.significant_point_id
and f1.en_route_rte_id = awid
union
select f1.code_sort + 1 st, f2.airway_point2 pid,f3.txt_name || decode(f3.tab, 'DES', '', f3.tab) pnm
from rte_seg f1, segment f2, airway_point f3
where f1.segment_id = f2.segment_id
and f2.airway_point2 = f3.significant_point_id
and f1.code_sort =(select max(code_sort)from rte_seg where rte_seg.en_route_rte_id = f1.en_route_rte_id)
and f1.en_route_rte_id = awid
order by st
);
IF cur_pnt%NOTFOUND THEN --如果游标内没数据,返回空表
RETURN dt;
END IF;
loop
FETCH cur_pnt
INTO dr.srt, dr.pid, dr.pnm;
EXIT WHEN cur_pnt%NOTFOUND; --到达游标结束,这行位置不能放最后,否则会重复一行
dt.extend(); --dt增加一行新行
dt(dt.count()) := dr; --dt最后一行=dr
END LOOP;
if pid1=0 or pid2=0 then --如果输入变量首点id或末点id 为0 表示返回所有航路走向
return dt;
end if;
n1:=-1; --初始值,用于判断时候再航路上找到输入点
n2:=-1;
for v in 1..dt.count() loop --从第一行到dt表的最后一行
if pid1 = dt(v).pid then n1:=dt(v).srt; --找到n1 n2对应位置
elsif pid2 = dt(v).pid then n2:=dt(v).srt;
end if;
end loop;
if n1=-1 or n2=-1 then --至少有一点没匹配上,返回空表
return dtt;
end if;
if n1<n2 then --点1序号小于点2序号,正常循环
for v in n1..n2 loop
if dt(v).srt >= n1 and dt(v).srt<=n2 then --dt(v).srt 从表结构逐级访问行结构、字段结构
dtt.extend();
dtt(dtt.count()):= dt(v);
end if;
end loop;
end if;
if n1>n2 then --如果n1>n2说明p1,p2顺序颠倒
tm:=n1;
while tm >= n2 LOOP
begin
dtt.extend();
dtt(dtt.count()):= dt(tm);
tm:= tm - 1;
end;
end LOOP;
end if;
return dtt;
end;
////////////////////////////////////////////////////////////////
方案2 不用游标 关键是 for myrow in (select ...) loop 函数 其余与方案一相同
////////////////////////////////////////////////////////////////
create or replace function subairway(pid1 in number,
awid in number,
pid2 in number,
ishis in number default 0 ) return tab_pnt is
--函数功能是返回awid航路两点间的所有航路点,使用此函数获得某航路两点间的所有点后时,不能用srt排序,否则永远只能得到按原航路顺序的点串,而不是按入点到出点顺序的点串。
dr row_pnt := row_pnt(0, 0, null); --type 行类型 每条点记录 create or replace type row_pnt is object(srt number(5),pid number(11),pnm varchar2(50))
dt tab_pnt:= tab_pnt(); --type 表类型,返回航路所有点 create or replace type tab_pnt as table of row_pnt
dtt tab_pnt:= tab_pnt(); --结果表,两点之间的所有表记录
-- 表类型和行类型必须先初始化,否则编译不错但运行会提示错误
n1 number(5); --两点在航路走向中的序号
n2 number (5);
tm number(5);
begin
if ishis=1 then --2016.9.7 原来写的临时航路居然找不到了,重写
for myrow in
( select sort st, airway_point_id pid, airway_point_name pnm from his_airway_pnts
where airway_id=awid
order by sort
)
loop
dr:=row_pnt(myrow.st,myrow.pid,myrow.pnm);
dt.extend(); --dt增加一行新行
dt(dt.count()) := dr; --dt最后一行=dr
END LOOP;
else
for myrow in
(
select st,pid,pnm from (
select f1.code_sort st,f2.airway_point1 pid,f3.txt_name || decode(f3.tab, 'DES', '', f3.tab) pnm
from rte_seg f1, segment f2, airway_point f3
where f1.segment_id = f2.segment_id
and f2.airway_point1 = f3.significant_point_id
and f1.en_route_rte_id = awid
union
select f1.code_sort + 1 st, f2.airway_point2 pid,f3.txt_name || decode(f3.tab, 'DES', '', f3.tab) pnm
from rte_seg f1, segment f2, airway_point f3
where f1.segment_id = f2.segment_id
and f2.airway_point2 = f3.significant_point_id
and f1.code_sort =(select max(code_sort)from rte_seg where rte_seg.en_route_rte_id = f1.en_route_rte_id)
and f1.en_route_rte_id = awid
order by st
)
)
loop
dr:=row_pnt(myrow.st,myrow.pid,myrow.pnm);
dt.extend(); --dt增加一行新行
dt(dt.count()) := dr; --dt最后一行=dr
END LOOP;
end if;
if pid1=0 or pid2=0 then --如果输入变量 首点id或末点id 为0 表示返回所有航路走向
return dt;
end if;
n1:=-1; --初始值,用于判断时候再航路上找到输入点
n2:=-1;
for v in 1..dt.count() loop --从第一行到dt表的最后一行
if pid1 = dt(v).pid then n1:=dt(v).srt; --找到n1 n2对应位置
elsif pid2 = dt(v).pid then n2:=dt(v).srt;
end if;
end loop;
if n1=-1 or n2=-1 then --至少有一点没匹配上,返回空表
return dtt;
end if;
if n1<n2 then --点1序号小于点2序号,正常循环
for v in n1..n2 loop
if dt(v).srt >= n1 and dt(v).srt<=n2 then --dt(v).srt 从表结构逐级访问行结构、字段结构
dtt.extend();
dtt(dtt.count()):= dt(v);
end if;
end loop;
end if;
if n1>n2 then --如果n1>n2说明p1,p2顺序颠倒
tm:=n1;
while tm >= n2 LOOP
begin
dtt.extend();
dtt(dtt.count()):= dt(tm);
dtt(dtt.count()).srt:=n1-tm+1; --2016.9.7 倒序排列时,为了让序号体现真正的从小到大顺序,改写每点序号
tm:= tm - 1;
end;
end LOOP;
end if;
return dtt;
end;
2015.1.15 利用Oracle函数返回表结果 重大技术进步!的更多相关文章
- 2015.1.15 利用Oracle函数插入表结构 Bulk collect into 不用循环,简洁高效
如果表结构只对应一个字段,可以 select col1 bulk collect into 变量,不用游标循环,简洁高效 create or replace function get_airway_s ...
- 浅谈Oracle函数返回Table集合
在调用Oracle函数时为了让PL/SQL 函数返回数据的多个行,必须通过返回一个 REF CURSOR 或一个数据集合来完成.REF CURSOR 的这种情况局限于可以从查询中选择的数据,而整个集合 ...
- 160628、利用Oracle rownum让表排序字段值连续
利用Oracle rownum让表排序字段值连续 1.需求说明 表(eval_index)中有字段如下: 表字段 描述 说明 ID 主键 GROUP_ID 分组编号 SORT_NUM 排序序号 按照分 ...
- Oracle的函数返回表类型(转)
在SQL Server中有表变量,可以在function中方便地返回,习惯SQL Server或者需要把脚本从SQL Server转到Oracle中的朋友可以都会碰到这个问题. Oracle的func ...
- oracle函数返回结果集
一.用自定义类型实现 1.创建表对象类型. 在Oracle中想要返回表对象,必须自定义一个表类型,如下所示: create or replace type type_table is table of ...
- 2015.1.15 利用航线id取所有点的函数创建视图
1.根据航路id取所有航路点的函数 create or replace function alinepnts(alid in number) return tab_airline_pnt is --返 ...
- C# ODP.NET 调用Oracle函数返回值时报错的一个解决方案
有人在社区问到:C#调用Oracle中自定义函数的返回值时,无法正常调用.但在PL/SQL中正常调用返回. 于是动手一试: 1.准备函数(Oralce 11g.2.0.0.4) CREATE OR R ...
- SQL函数返回表的示例-Z
create function [dbo].[GetOperateCustGroup] ( ), ) ) returns @TempTable table (MaxPrice float,MinPri ...
- oracle pipelined返回值函数 针对数据汇总统计 返回结果集方法
近期需要一个汇总统计,由于数据太多,数据量太大所以在java程序中实现比较困难.若用后台程序统计,数据不能保证实时,同时实现周期比较长.顾使用函数返回结果集的方式,在不增加临时表的情况下实时获取数据. ...
随机推荐
- Python httpServer服务器(初级)
使用原生的python开发的web服务器,入门级! #!/usr/bin/python # -*- coding: UTF-8 -*- import os #Python的标准库中的os模块包含普遍的 ...
- Centos7 docker容器 搭建
Dockerfile 文件如下: # # MAINTAINER Carson,C.J.Zeong <zcy@nicescale.com> # DOCKER-VERSION # # Dock ...
- Phoenix on HBase
(一)概要 Apache Phoenix是基于BSD许可开源的一个Java中间层,可以让开发者在Apache HBase上执行SQL查询.Apache Phoenix主要特性: 嵌入式的JDBC驱动, ...
- ASP.NET上传文件,已经上传的大小保存在session中,在另一个页面中读取session的值不行
想自己做个ASP.NET上传文件时显示进度条的, 按照自己的想法,其实也就是显示每次已经上传的字节,从网上找到一个方法是能够把文件变成流以后再慢慢写入的,我在那个循环写入的时候每循环一次都把已经上传的 ...
- 写hibernate.cfg.xml时报错The content of element type "property" must match "(meta*,(column|formula)*,type?)".
原配置文件是这样的 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-ma ...
- L120 单词造句
The old lady sits on a mobile chair every morning.The book contains scandalous text. The current sur ...
- AutoCAD2014的安装与激活
1.安装包与激活文件的下载 链接:https://pan.baidu.com/s/1I2-x9T__sQAgtvjkOyc_1Q 密码:5pd1 2.CAD的安装 此过程没什么特殊要求,安装时随便输入 ...
- Communication System(动态规划)
个人心得:百度推荐的简单DP题,自己做了下发现真得水,看了题解发现他们的思维真得比我好太多太多, 这是一段漫长的锻炼路呀. 关于这道题,我最开始用DP的思路,找子状态,发现自己根本就不会找DP状态数组 ...
- axios 请求报错
报错如下: 解决:axios的请求配置中的baseURL配置错误,修改好即可. 报错前: baseURL: "192.168.30.220:3000", 解决后:baseURL: ...
- Tomcat设计模式分析(转) 2
Tomcat 系统架构与设计模式,第 2 部分: 设计模式分析 这个分为两个部分的系列文章研究了 Apache Tomcat 服务器的系统架构以及其运用的很多经典设计模式.第 1 部分 分析了 Tom ...