-- 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函数返回表结果 重大技术进步!的更多相关文章

  1. 2015.1.15 利用Oracle函数插入表结构 Bulk collect into 不用循环,简洁高效

    如果表结构只对应一个字段,可以 select col1 bulk collect into 变量,不用游标循环,简洁高效 create or replace function get_airway_s ...

  2. 浅谈Oracle函数返回Table集合

    在调用Oracle函数时为了让PL/SQL 函数返回数据的多个行,必须通过返回一个 REF CURSOR 或一个数据集合来完成.REF CURSOR 的这种情况局限于可以从查询中选择的数据,而整个集合 ...

  3. 160628、利用Oracle rownum让表排序字段值连续

    利用Oracle rownum让表排序字段值连续 1.需求说明 表(eval_index)中有字段如下: 表字段 描述 说明 ID 主键 GROUP_ID 分组编号 SORT_NUM 排序序号 按照分 ...

  4. Oracle的函数返回表类型(转)

    在SQL Server中有表变量,可以在function中方便地返回,习惯SQL Server或者需要把脚本从SQL Server转到Oracle中的朋友可以都会碰到这个问题. Oracle的func ...

  5. oracle函数返回结果集

    一.用自定义类型实现 1.创建表对象类型. 在Oracle中想要返回表对象,必须自定义一个表类型,如下所示: create or replace type type_table is table of ...

  6. 2015.1.15 利用航线id取所有点的函数创建视图

    1.根据航路id取所有航路点的函数 create or replace function alinepnts(alid in number) return tab_airline_pnt is --返 ...

  7. C# ODP.NET 调用Oracle函数返回值时报错的一个解决方案

    有人在社区问到:C#调用Oracle中自定义函数的返回值时,无法正常调用.但在PL/SQL中正常调用返回. 于是动手一试: 1.准备函数(Oralce 11g.2.0.0.4) CREATE OR R ...

  8. SQL函数返回表的示例-Z

    create function [dbo].[GetOperateCustGroup] ( ), ) ) returns @TempTable table (MaxPrice float,MinPri ...

  9. oracle pipelined返回值函数 针对数据汇总统计 返回结果集方法

    近期需要一个汇总统计,由于数据太多,数据量太大所以在java程序中实现比较困难.若用后台程序统计,数据不能保证实时,同时实现周期比较长.顾使用函数返回结果集的方式,在不增加临时表的情况下实时获取数据. ...

随机推荐

  1. [转载]ORA-00313:无法打开日志组1(线程 1)的成员_ORA-00312:

    原文地址:1)的成员_ORA-00312:">ORA-00313:无法打开日志组1(线程 1)的成员_ORA-00312:作者:Sweet_薇薇毅 今天用系统清理工具把系统垃圾清理了一 ...

  2. HDFS数据完整性

    数据完整性 Hadoop用户肯定都希望系统在存储和处理数据时不会丢失或损坏任何数据.尽管磁盘或网络上的每个I/O操作不太可能将错误引入自己正在读/写的数据中,但是如果系统中需要处理的数据量大到Hado ...

  3. DATEDIFF 的用法

    DECLARE @date DATETIME = '2017-12-26 00:00:00';DECLARE @date2 DATETIME = DATEADD(DAY, 1, @date);DECL ...

  4. Spring获取bean的一种方式

    随便一百度,网上一大把,并且还不止一种.所以这里就只记录目前用的一种好了. 实现ApplicationContextAware接口 即可: import org.springframework.bea ...

  5. 使用Jenkins进行持续集成

    首先,我们从Jenkins官方网站https://jenkins.io/下载最新的war包.虽然Jenkins提供了Windows.Linux.OS X等各种安装程序,但是,这些安装程序都没有war包 ...

  6. JMeter接口测试报错,反馈和postman不一样(二)

    我总共现在有两个可以学习的接口,昨天测试一个接口发现问题解决后,今天测试另外一个发现又有问题了 这一次还是反馈显示不一样 要么 这种情况是直接从postman里面拿过来的数据,没做处理  报not j ...

  7. js装饰者模式

    装饰者模式是为已有的功能动态地添加更多功能的一种方式.当系统需要新功能的时候,是向旧的类中添加新的代码.这些新加的代码通常装饰了原有类的核心职责或主要行为,在主类中加入了新的字段,新的方法和新的逻辑, ...

  8. iOS学习笔记之正则表达式

    前言 基本上每个 App 都有登录注册功能,在登录注册时需要验证用户所输入的内容是否符合规定:有时要在字符串中查找并截取符合要求的字符串,这时就需要用到正则表达式.正则表达式看起来晦涩难懂,没有什么规 ...

  9. python定制

    1.简单定制   a.使用time模块的localtime方法获取时间 b.time.localtime返回struct_time的时间格式 c.表现你的类:__str__和__repr__ 注:当属 ...

  10. 搜索5--noi1700:八皇后问题

    搜索5--noi1700:八皇后问题 一.心得 二.题目 1700:八皇后问题 查看 提交 统计 提问 总时间限制:  10000ms 内存限制:  65536kB 描述 在国际象棋棋盘上放置八个皇后 ...