时间: 2021-07-31 作者:daque
附加的字符串
作家:steven feuerstein
此刻你不妨经过字符串创造索引普及本能。
很多pl/sql步调对数据举行操纵,常常是经过运用sql在数据库市直接操纵数据。你常常还须要在pl/sql步调自己内证明和处置数据。这个步调数据大概由少许独立的值(标量)构成。然而在其余很多情景下,你大概要处置更搀杂的数据构造,从记载到东西(东西典型的范例)以至是列表。
列表(以及以更搀杂的办法表白的数组)是步调职工具箱中最要害的元素。为了创造和处置那些列表,pl/sql供给了形形色色称作汇合的构造,如:嵌套表,可变数组和关系数组。
在oracle9i第2版中引入的关系数组代替了索引表(它在oracle第88中学代替了pl/sql表)。关系数组引入了要害的新功效。在oracle9i第2版中,你此刻不妨:
设置在其里面包括其它汇合的汇合。那些被叫作多层汇合的列表使你不妨在pl/sql数据构造里面越发直觉和径直地对实际寰球的情景建立模型。我在oracle期刊2002年5/6月号的作品"多档次的编制程序"中引见过这个个性。
咱们不妨创造经过字符串来创造索引行的汇合(并可赶快举行检索)。比方,公司的名字在该汇合中不妨是"行号"。 本篇作品证明还好吗经过串来对关系数组装立索引和还好吗设置如许的汇合。
用字符串来创造索引
有一个新的本领可用来设置和操纵pl/sql一定的汇合。更加是,你除去运用行号如许的平头值来创造索引除外,你还不妨经过字符串来创造索引。这个本领供给了十分要害的特殊精巧性。请看清单第11中学的例子。
在清单第11中学,第2行声领会一个经过最大长度为64个字符的串创造了索引的保存数字的关系数组典型。第3行和第4行鉴于这个典型声领会2个关系数组。第5行声领会一个变量来保存汇合中的行号。第6行声领会一个变量来保存"极限值"(最低和最高的行索引值)。请提防,由于这个变量会接受一个鉴于串索引的值,以是它被证明为一个字符串。在第8行和第9行中,我将值赋给了country_population。历次我都把国度的人丁数赋给汇合中的一条龙。那一条龙的索引即是它的国名。在第11行中,我从汇合中检索出一个值。请提防,我经过国名来决定那一条龙,而剧本将归来相映的人丁数。从第18行到第20行,我获得第一个设置的行值,而后表露它,接着表露谁人国度的人丁数。数据库是还好吗决定第一条龙的呢?第一条龙是经过数据库中字符集一定的排序程序来决定的。从第22行到第24行,我运用对第一个设置的行值的沟通的进程来获得结果一个设置的行值。
对于字符串索引的汇合你大概须要渐渐地风气,然而这种汇合经过挪用first、last、prior和next本领获得的归来值是字符串而不是数。
字符串索引汇合的运用
干什么你该当运用字符串而不是数来创造索引呢?假如你须要在你的步调中对职工的消息举行少许洪量的处置。你大概需重复地处置一组选定的雇员的消息,比方,按雇员的id号子、姓氏和社会保障号子(对于美利坚合众国除外的少许国度大概是相映的身份证号子)来探求职工。
固然你不妨运用sql来实行那些工作,但这远不是最高效的实行办法。即使你须要屡次处置一组数目很大的静态数据,那么你不妨改为把这组数据从数据库中移到一组汇合中。考察鉴于汇合的数据比运用sql引擎来考察数据要快得多。
接下来你不妨运用那些汇合的鉴于字符串和鉴于平头的索引入抄袭表(你仍旧把该表的数据从数据库中传出来了)的主键和私有的索引。这个本领的一个大略的例子已在清单2的代码中展现出。
在清单第22中学,第1行到第4行声领会两个关系数组典型。提防,我不妨在index by子句中运用%type,在其它的子句中运用pls_integer包办binary_integer。那些都是oracle9i release 2的新功效。在第6行到第8行,我声领会将用来供给加入数据的多个赶快进口点的汇合。从第12行到第21行,load_arrays进程表露了从数据库表将数据传递到一个或多个(在该范例中是3个汇合)是如许得简单。我经过运用各别的字段值动作要害字,把整行的雇员数据动作一个记载寄存到每一个汇合中。在第17行中,我把姓氏用作索引值。在第18行中,我运用社会安定号子动作索引值。在第19行中,主要害字动作索引值(它是一个把平头索引动作一个"智能要害字"的十分保守的运用)。在第27行中,我经过运用字符串和平头索引值对两个各别汇合中的报酬域举行比拟。
用字符串作索引的多档次汇合
我仍旧创造了一个风趣的新适用步调,叫作codecheck,它运用了 oracle9i第2版汇合的少许巩固个性。该步调包提防查看all_argument数据字典视图的实质,再不领会一定的步调包和独立的运用步调其代码能否适合源代码规范或揭穿少许安排题目(比方不精确的超负载)。
all_arguments包括对于每个保存在数据库(贯穿的用户在其上具有execute权力中)的进程和因变量的每个参数或自变量的消息。all_arguments中的简单行包括对于一个自变量(大概,在某些情景下,一个自变量的一个域(field)或一个元素)的消息。底下是为all_argument设置的字段的一个子集:
名字 空值? 典型 --------------- -------- ------------owner 非空值 varchar2(30)object_name varchar2(30)package_name varchar2(30)overload varchar2(40)argument_name varchar2(30)position 非空值 numberdata_level 非空值 numberdata_type varchar2(30)default_value longin_out varchar2(9)
很快你就会看到嵌入在那些行中的档次:每个东西(owner.object_name)大概超载(overload)(即使不超载或是一个负数,则overload是空值)。overloading中的每一个自变量都有一个场所,而在谁人场所内你不妨有自变量消息的多个"档次"。换句话说,
object_name overload argument_name position level
因为篇幅所限我不大概供给codecheck步调包中太多适用步调的实行。不管怎样,我很欣喜与您瓜分我为了轻快地赶快领会all_arguments的实质而把它的数据传递到我的汇合中而写的代码。
我在codecheck步调包长进行第一次传递中,我设置了一个不妨大略地映照数据字典视图的汇合典型和汇合,如次所示:
create or replace package body codecheckis type args_t is table of all_arguments%rowtype index by binary_integer; arguments args_t;
正如清单3所示,我经过运用设置的汇合,只运用了很小批的代码它就不妨为一定的步调赢得数据并把它插入到我的汇合中。
设置嵌套的汇合
然而,我在写完清单3中的代码后赶快认识到,我正在以落伍的办法思拷问题。我的安置是先填满我的汇合接着写少许搀杂的代码来扫描自变量汇合,而后搜索少许工作,诸如:
一个步调包中私有步调的代号和名字。我大概所有有12个步调,但因为超载所以惟有3个各别的步调名。
顶级自变量项(其data_level = 0)。
这即是在汇合顶用于标识一个步调中断和另一个步调发端的那些自变量。 处置在all_arguments视图中数据的构造题目并写出所须要的代码是我的工作。
假设我设置多个嵌套的汇合来保存这个数据将会还好吗呢?大概经过这个本领,汇合的该构造不妨使我越发简单地回复少许我的题目。在过程推敲和尝试了少许可选计划之后,我获得了如清单4所示的汇合典型的档次构造。
图1:在all_arguments汇合映照中的四层嵌套
底下是对清单4实质的刻画。像如许的情景最佳是运用"自底进取",大概是从档次的最外层到最里面的汇合的接洽本领。在第15行中,我声领会典型为programs_t的汇合。这个独立的汇合将包括all_arguments视图中的十足消息,正像我的第一次试验中那么,然而该消息的构造却实足各别。在第12行和第13行中,我声领会汇合典型programs_t。这个典型的汇合中的每一条龙包括相关一个给定步调名的十足overloadings的自变量的一切关系消息。请提防,索引是东西的名字。在第9行和第10行中,我声领会汇合典型overloadings_t。这个典型的汇合中的每一条龙包括相关一个步调的一个简单overloading的自变量的一切关系消息。此刻我再次运用一个平头索引,由于在这种情景下要害字是all_arguments视图中的overload字段的值。在第6行和第7行中,我声领会汇合典型arguments_t。这个典型的汇合中的每一条龙包括一个一定overloading的一个简单参数或自变量的一切关系消息。我仍旧运用一个平头索引,由于在该情景下,要害字是all_arguments的position字段的值(即参数列表中的场所)在第3行和第4行中,我声领会汇合典型breakouts_t。这个典型的汇合中的每一条龙包括一个自变量的一个简单元素的一切关系消息。这大概是一条龙也大概是多行数据。即使比方这个题目中的自变量是一个有15个域的记载,那么这个汇合至罕见15行。我借助一个平头索引,由于在这个例子中要害字是all_arguments视图中的level字段的值(在参数列表中0表白本质的自变量)。
能否令人有些迷惑?开始,不要只盯着all_arguments视图中数据的搀杂性。我只想给你一个在我的代码中须要操纵的变量的体验。接下来咱们看一下图第11中学的图表。提防在all_arguments视图中嵌套的档次是还好吗大略地以那些各别的档次来表白的。
有了g_programs汇合之后,让咱们再次察看如清单5所示的codecheck包中的load_arguments进程。
清单3中的load_arguments进程和清单第5中学的本子有什么各别?完全地看特殊小。独一各别的语句是在清单5的第12行到第16行。底下是在清单3中的较早的大略赋值语句:
arguments ( nvl (arguments.last, 0) + 1) := rec;
在清单第5中学,它形成了:
g_programs (rec.object_name) (rec.overload) (rec.position) (rec.data_level) := rec;
这固然很搀杂,但它会为我处置那恐怖的搀杂性。比方,经过运用这个简单的赋值语句,我本质上把十足4个汇合中的一切行放到该档次构造中。当我实行这一处事后,只花了很少的代码就满意了我的检索数据的须要。比方,赢得total_sales因变量的第2个overloading的return子句的数据典型:
g_programs ('total_sales') -- locate (2) -- second overloading (0) -- return clause has position 0 (0) -- top-level argument .data_type -- value in the data_type field
在这种情景下,运用这个语法比编写和调节和测试扫描一个"平面(flat)"(oracle9i数据库之前)汇合所须要的论理来获得如许的消息代码要简单得多。
固然我并不憧憬你能登时实足领略那些搀杂的汇合构造的潜伏本领,我只蓄意这个段落的少许例子不妨起到举一反三的效率。
这么多的采用!
只有符合地运用,汇合将扶助咱们编写出更高效和更易懂的代码。将多档次的编制程序和用字符串创造索引不妨扶助咱们缩小搀杂性和缩小建立模型和操纵来自搀杂数据库安排的消息所需的源代码量。