Oracle PL/SQL-如何创建一个简单的数组变量?

我想创建一个内存中的数组变量,可以在我的 PL/SQL 代码中使用。我在 Oracle PL/SQL 中找不到任何使用纯内存的集合,它们似乎都与表相关联。我希望在我的 PL/SQL (C # 语法)中做类似的事情:

string[] arrayvalues = new string[3] {"Matt", "Joanne", "Robert"};

编辑: 甲骨文: 9i

563434 次浏览

可以对固定大小的数组使用 VARRAY:

declare
type array_t is varray(3) of varchar2(10);
array array_t := array_t('Matt', 'Joanne', 'Robert');
begin
for i in 1..array.count loop
dbms_output.put_line(array(i));
end loop;
end;

或无界数组的 TABLE:

...
type array_t is table of varchar2(10);
...

这里的“ table”一词与数据库表没有任何关系,令人困惑的是,这两种方法都创建了内存中的数组。

在添加元素之前,您需要初始化和扩展这个集合:

declare
type array_t is varray(3) of varchar2(10);
array array_t := array_t(); -- Initialise it
begin
for i in 1..3 loop
array.extend(); -- Extend it
array(i) := 'x';
end loop;
end;

第一个索引是1而不是0。

您只需声明一个 DBMS _ SQL. VARCHAR2 _ TABLE 来保存由 BINARY _ INTEGER 索引的内存变量长度数组:

DECLARE
name_array dbms_sql.varchar2_table;
BEGIN
name_array(1) := 'Tim';
name_array(2) := 'Daisy';
name_array(3) := 'Mike';
name_array(4) := 'Marsha';
--
FOR i IN name_array.FIRST .. name_array.LAST
LOOP
-- Do something
END LOOP;
END;

你可以使用一个关联数组(过去称为 PL/SQL 表) ,因为它们是一个内存数组。

DECLARE
TYPE employee_arraytype IS TABLE OF employee%ROWTYPE
INDEX BY PLS_INTEGER;
employee_array employee_arraytype;
BEGIN
SELECT *
BULK COLLECT INTO employee_array
FROM employee
WHERE department = 10;
--
FOR i IN employee_array.FIRST .. employee_array.LAST
LOOP
-- Do something
END LOOP;
END;

关联数组可以容纳任何类型的唱片。

希望能有所帮助, 奥利。

您也可以使用 < em > oracle defined collection

DECLARE
arrayvalues sys.odcivarchar2list;
BEGIN
arrayvalues := sys.odcivarchar2list('Matt','Joanne','Robert');
FOR x IN ( SELECT m.column_value m_value
FROM table(arrayvalues) m )
LOOP
dbms_output.put_line (x.m_value||' is a good pal');
END LOOP;
END;

我会使用内存数组。但是随着 .COUNT的改进,Uziberia 建议:

DECLARE
TYPE t_people IS TABLE OF varchar2(10) INDEX BY PLS_INTEGER;
arrayvalues t_people;
BEGIN
SELECT *
BULK COLLECT INTO arrayvalues
FROM (select 'Matt' m_value from dual union all
select 'Joanne'       from dual union all
select 'Robert'       from dual
)
;
--
FOR i IN 1 .. arrayvalues.COUNT
LOOP
dbms_output.put_line(arrayvalues(i)||' is my friend');
END LOOP;
END;

另一个解决方案是像@Jchomel 做的 给你那样使用 Hashmap。

注意:

使用 Oracle 12c,您可以 甚至直接查询数组

另一种解决方案是使用 Oracle 集合作为散列表:

declare
-- create a type for your "Array" - it can be of any kind, record might be useful
type hash_map is table of varchar2(1000) index by varchar2(30);
my_hmap hash_map ;
-- i will be your iterator: it must be of the index's type
i varchar2(30);
begin
my_hmap('a') := 'apple';
my_hmap('b') := 'box';
my_hmap('c') := 'crow';
-- then how you use it:


dbms_output.put_line (my_hmap('c')) ;


-- or to loop on every element - it's a "collection"
i := my_hmap.FIRST;


while (i is not null)  loop
dbms_output.put_line(my_hmap(i));
i := my_hmap.NEXT(i);
end loop;


end;

样品程序如下,并提供在链接也 https://oracle-concepts-learning.blogspot.com/

表或关联数组。

        DECLARE
TYPE salary IS TABLE OF NUMBER INDEX BY VARCHAR2(20);
salary_list salary;
name VARCHAR2(20);
BEGIN
-- adding elements to the table
salary_list('Rajnish') := 62000; salary_list('Minakshi') := 75000;
salary_list('Martin') := 100000; salary_list('James') := 78000;
-- printing the table name := salary_list.FIRST; WHILE name IS NOT null
LOOP
dbms_output.put_line ('Salary of ' || name || ' is ' ||
TO_CHAR(salary_list(name)));
name := salary_list.NEXT(name);
END LOOP;
END;
/

使用 varray 是不使用表复制我发现的 C # 代码的最快方法。

声明要在脚本中使用的公共数组类型

    type t_array is varray(10) of           varchar2(60);

这是您需要调用的函数——只需使用逗号分隔符查找传递过来的字符串中的值

function ConvertToArray(p_list IN VARCHAR2)
RETURN t_array
AS
myEmailArray t_array := t_array(); --init empty array
    

l_string                    varchar2(1000) := p_list || ','; - (list coming into function adding final comma)
l_comma_idx                 integer;
l_index                     integer := 1;
l_arr_idx                   integer := 1;
l_email                     varchar2(60);
    

BEGIN
    

LOOP
l_comma_idx := INSTR(l_string, ',', l_index);
EXIT WHEN l_comma_idx = 0;
        

l_email:= SUBSTR(l_string, l_index, l_comma_idx - l_index);
dbms_output.put_line(l_arr_idx || ' - ' || l_email);
        

myEmailArray.extend;
myEmailArray(l_arr_idx) := l_email;
        

l_index := l_comma_idx + 1;
l_arr_idx := l_arr_idx + 1;
END LOOP;
   

for i in 1..myEmailArray.count loop
dbms_output.put_line(myEmailArray(i));
end loop;
   

dbms_output.put_line('return count ' || myEmailArray.count);
RETURN myEmailArray;


--exception
--when others then
--do something


end ConvertToArray;

最后声明一个局部变量,调用函数并通过返回的内容进行循环

l_array          t_array;


l_Array := ConvertToArray('email1@gmail.com,email2@gmail.com,email3@gmail.com');




for idx in 1 .. l_array.count
loop
l_EmailTo := Trim(replace(l_arrayXX(idx),'"',''));
if nvl(l_EmailTo,'@') = '@' then
dbms_output.put_line('Empty: l_EmailTo:' || to_char(idx) || l_EmailTo);
else
dbms_output.put_line
( 'Email ' || to_char(idx) ||
' of array contains: ' ||
l_EmailTo
);
end if;
end loop;