PLS-00382: 填充关联数组时表达式的类型错误 table
PLS-00382: expression is of wrong type in populating an associative array table
我的数据库中有 table 这种结构
现在我想要它里面的所有值都在一个关联数组中,该数组由 job_id%type 索引,它是一个 varchar2,所以我在创建一个程序来测试它之前先创建了这个匿名块,然后我想用结果填充我的关联数组:
DECLARE
TYPE jobs_tab_type IS TABLE OF jobs%rowtype INDEX BY jobs.job_id%type;
jobstab jobs_tab_type;
BEGIN
FOR rec IN (SELECT * FROM jobs)
LOOP
jobstab(rec.job_id) := rec.job_id;
END LOOP;
END;
我确定这是错误的方法,因为我遇到了这个错误:PLS-00382: expression is of wrong type
,但同时我不知道不知道是否有任何正确的方法可以做到这一点。我看过文档,但所有示例都是使用用户定义的字符串来保存 job_id,但问题是我需要索引 job_id 而不是用户定义的字符串。在 PL/SQL 中有什么方法可以解决这个问题吗?
你的关联数组的值是整条记录。因此,只需从您的这行代码中删除 .job_id
。
jobstab(rec.job_id) := rec.job_id;
换句话说,该行应该是
jobstab(rec.job_id) := rec;
您不需要 INDEX BY jobs.job_id%type
的索引。它使您的代码更加复杂。 INDEX BY
确定集合的 index - 即用于指示集合中位置的字符。 不需要 成为您从中获取 %rowtype 的 table 中的一列。
如果您想根据有意义的字符串引用集合,通常会使用 INDEX BY VARCHAR2
,例如 capitals('United States') = 'Washingston'
现在,关于你的问题。这是原问题的答案:
create table jobs
(job_id VARCHAR2(10)
,job_title VARCHAR2(30)
,min_salary NUMBER
,max_salary NUMBER
);
INSERT INTO jobs (job_id, job_title, min_salary, max_salary) VALUES ('a','CLERK',100,500);
INSERT INTO jobs (job_id, job_title, min_salary, max_salary) VALUES ('b','PRESIDENT',1000,5000);
INSERT INTO jobs (job_id, job_title, min_salary, max_salary) VALUES ('c','SALESMAN',500,800);
DECLARE
TYPE jobs_tab_type IS TABLE OF jobs%rowtype INDEX BY jobs.job_id%type;
jobstab jobs_tab_type;
l_idx VARCHAR2(100);
BEGIN
FOR rec IN (SELECT * FROM jobs)
LOOP
jobstab(rec.job_id) := rec;
END LOOP;
l_idx := jobstab.FIRST;
WHILE (l_idx IS NOT NULL) LOOP
dbms_output.put_line(l_idx ||': '||jobstab(l_idx).job_title);
l_idx := jobstab.NEXT(l_idx);
END LOOP;
END;
/
a: CLERK
b: PRESIDENT
c: SALESMAN
请注意,在这个块中,循环遍历元素有点乏味,因为索引不是整数。现在让我们看一下相同的功能,但使用 INDEX BY BINARY_INTEGER
:
DECLARE
TYPE jobs_tab_type IS TABLE OF jobs%rowtype INDEX BY BINARY_INTEGER;
jobstab jobs_tab_type;
l_idx NUMBER := 1;
BEGIN
-- example 1: using a cursor for loop
-- FOR rec IN (SELECT * FROM jobs)
-- LOOP
-- jobstab(l_idx) := rec;
-- l_idx := l_idx + 1;
-- END LOOP;
-- example 2: using bulk collect
SELECT * BULK COLLECT INTO jobstab FROM jobs;
FOR r IN 1 .. jobstab.COUNT LOOP
dbms_output.put_line(r ||': '||jobstab(r).job_title);
END LOOP;
END;
/
1: CLERK
2: PRESIDENT
3: SALESMAN
由于数字索引,循环遍历集合的值更简单,而且它也可以使用 BULK COLLECT
语句隐式分配。
我的数据库中有 table 这种结构
现在我想要它里面的所有值都在一个关联数组中,该数组由 job_id%type 索引,它是一个 varchar2,所以我在创建一个程序来测试它之前先创建了这个匿名块,然后我想用结果填充我的关联数组:
DECLARE
TYPE jobs_tab_type IS TABLE OF jobs%rowtype INDEX BY jobs.job_id%type;
jobstab jobs_tab_type;
BEGIN
FOR rec IN (SELECT * FROM jobs)
LOOP
jobstab(rec.job_id) := rec.job_id;
END LOOP;
END;
我确定这是错误的方法,因为我遇到了这个错误:PLS-00382: expression is of wrong type
,但同时我不知道不知道是否有任何正确的方法可以做到这一点。我看过文档,但所有示例都是使用用户定义的字符串来保存 job_id,但问题是我需要索引 job_id 而不是用户定义的字符串。在 PL/SQL 中有什么方法可以解决这个问题吗?
你的关联数组的值是整条记录。因此,只需从您的这行代码中删除 .job_id
。
jobstab(rec.job_id) := rec.job_id;
换句话说,该行应该是
jobstab(rec.job_id) := rec;
您不需要 INDEX BY jobs.job_id%type
的索引。它使您的代码更加复杂。 INDEX BY
确定集合的 index - 即用于指示集合中位置的字符。 不需要 成为您从中获取 %rowtype 的 table 中的一列。
如果您想根据有意义的字符串引用集合,通常会使用 INDEX BY VARCHAR2
,例如 capitals('United States') = 'Washingston'
现在,关于你的问题。这是原问题的答案:
create table jobs
(job_id VARCHAR2(10)
,job_title VARCHAR2(30)
,min_salary NUMBER
,max_salary NUMBER
);
INSERT INTO jobs (job_id, job_title, min_salary, max_salary) VALUES ('a','CLERK',100,500);
INSERT INTO jobs (job_id, job_title, min_salary, max_salary) VALUES ('b','PRESIDENT',1000,5000);
INSERT INTO jobs (job_id, job_title, min_salary, max_salary) VALUES ('c','SALESMAN',500,800);
DECLARE
TYPE jobs_tab_type IS TABLE OF jobs%rowtype INDEX BY jobs.job_id%type;
jobstab jobs_tab_type;
l_idx VARCHAR2(100);
BEGIN
FOR rec IN (SELECT * FROM jobs)
LOOP
jobstab(rec.job_id) := rec;
END LOOP;
l_idx := jobstab.FIRST;
WHILE (l_idx IS NOT NULL) LOOP
dbms_output.put_line(l_idx ||': '||jobstab(l_idx).job_title);
l_idx := jobstab.NEXT(l_idx);
END LOOP;
END;
/
a: CLERK
b: PRESIDENT
c: SALESMAN
请注意,在这个块中,循环遍历元素有点乏味,因为索引不是整数。现在让我们看一下相同的功能,但使用 INDEX BY BINARY_INTEGER
:
DECLARE
TYPE jobs_tab_type IS TABLE OF jobs%rowtype INDEX BY BINARY_INTEGER;
jobstab jobs_tab_type;
l_idx NUMBER := 1;
BEGIN
-- example 1: using a cursor for loop
-- FOR rec IN (SELECT * FROM jobs)
-- LOOP
-- jobstab(l_idx) := rec;
-- l_idx := l_idx + 1;
-- END LOOP;
-- example 2: using bulk collect
SELECT * BULK COLLECT INTO jobstab FROM jobs;
FOR r IN 1 .. jobstab.COUNT LOOP
dbms_output.put_line(r ||': '||jobstab(r).job_title);
END LOOP;
END;
/
1: CLERK
2: PRESIDENT
3: SALESMAN
由于数字索引,循环遍历集合的值更简单,而且它也可以使用 BULK COLLECT
语句隐式分配。