我想创建一个可以在我的PL / SQL代码中使用的内存数组变量。我在Oracle PL / SQL中找不到任何使用纯内存的集合,它们似乎都与表相关联。我希望在我的PL / SQL(C#语法)中做这样的事情:
string[] arrayvalues = new string[3] {"Matt", "Joanne", "Robert"};
修改 Oracle:9i
答案 0 :(得分:218)
您可以将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;
或无表格数组的表格:
...
type array_t is table of varchar2(10);
...
这里的“表”一词与数据库表无关,令人困惑。这两种方法都创建了内存数组。
使用其中任何一个,您需要在添加元素之前初始化和扩展集合:
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。
答案 1 :(得分:57)
你可以声明一个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;
关联数组可以保存任何记录类型。
希望它有所帮助, 奥利。
答案 2 :(得分:11)
另一种解决方案是将Oracle Collection用作Hashmap:
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;
答案 3 :(得分:9)
您还可以使用 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;
我会使用内存数组。但是,随着uziberia提出的.COUNT
改进:
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 here。
<强> NB:强>
使用Oracle 12c,您可以even query arrays directly now!
答案 4 :(得分:0)
以下示例程序并在https://oracle-concepts-learning.blogspot.com/链接上提供
plsql表或关联的数组。
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;
/