Sql I';我被这个问题难住了
在这个查询中,我想插入关联数组元素输出,它在表Sql I';我被这个问题难住了,sql,oracle,plsql,Sql,Oracle,Plsql,在这个查询中,我想插入关联数组元素输出,它在表phonebook中打印一个电话号码,并将这个输出插入这个表中 CREATE TABLE Phonebook ( areacode VARCHAR2(3), prefix VARCHAR2(3), num VARCHAR2(4) ); SET SERVEROUTPUT ON DECLARE TYPE phone_num IS RECORD ( arac Phonebook.area
phonebook
中打印一个电话号码,并将这个输出插入这个表中
CREATE TABLE Phonebook
(
areacode VARCHAR2(3),
prefix VARCHAR2(3),
num VARCHAR2(4)
);
SET SERVEROUTPUT ON
DECLARE
TYPE phone_num IS RECORD (
arac Phonebook.areacode%TYPE, prf Phonebook.prefix%TYPE, recnum phonebook.num%TYPE);
TYPE phonenum IS TABLE OF phone_num INDEX BY BINARY_INTEGER;
aaaray phonenum;
aaaray2 phonenum;
CURSOR c IS
SELECT phone_number
from employees
where department_id IN (20,80,90);
diff INTEGER := 0;
BEGIN
for i in c loop
diff := diff + 1;
IF SUBSTR (i.phone_number, 1, 3 ) = '011' then
DBMS_OUTPUT.PUT_LINE('International');
ELSIF SUBSTR (i.phone_number, 1, 3 ) = '515' then
aaaray(diff).arac := SUBSTR (i.phone_number, 1, 3 );
aaaray(diff).prf := SUBSTR (i.phone_number, 5, 3 );
aaaray(diff).recnum := SUBSTR (i.phone_number, 9, 4 );
DBMS_OUTPUT.PUT_LINE('phone number is domestic ' || aaaray(diff).arac || aaaray(diff).prf || aaaray(diff).recnum);
elsif SUBSTR (i.phone_number, 1, 3 ) = '603' then
aaaray2(diff).arac := SUBSTR (i.phone_number, 1, 3 );
aaaray2(diff).prf := SUBSTR (i.phone_number, 5, 3 );
aaaray2(diff).recnum := SUBSTR (i.phone_number, 9, 4 );
DBMS_OUTPUT.PUT_LINE('phone number is domestic ' || aaaray2(diff).arac|| aaaray2(diff).prf || aaaray2(diff).recnum);
else
DBMS_OUTPUT.PUT_LINE('no display');
end if;
end loop;
insert into Phonebook values (aaaray.arac, aaaray.prf, aaaray.recnum) ;
insert into Phonebook values (aaaray2.arac, aaaray2.prf, aaaray2.recnum) ;
END;
/
错误:
错误报告ORA-06550:第39行第66列:
PLS-00302:必须声明组件“RECNUM”
ORA-06550:第39行第66列:
PL/SQL:ORA-00984:此处不允许列
ORA-06550:第39行第4列:
您正在尝试在电话簿表中插入数组 替换以下内容:
insert into Phonebook values (aaaray.arac, aaaray.prf, aaaray.recnum) ;
insert into Phonebook values (aaaray2.arac, aaaray2.prf, aaaray2.recnum) ;
与
您可以将insert语句放入for循环中。正如我所看到的,除了存储数据之外,您没有在收集变量方面做任何其他事情,您也可以只使用一个变量-
DECLARE
TYPE phone_num IS RECORD (
arac Phonebook.areacode%TYPE, prf Phonebook.prefix%TYPE, recnum phonebook.num%TYPE);
TYPE phonenum IS TABLE OF phone_num INDEX BY BINARY_INTEGER;
aaaray phonenum;
CURSOR c IS
SELECT phone_number
from employees
where department_id IN (20,80,90);
diff INTEGER := 0;
BEGIN
for i in c loop
diff := diff + 1;
IF SUBSTR (i.phone_number, 1, 3 ) = '011' then
DBMS_OUTPUT.PUT_LINE('International');
ELSIF SUBSTR (i.phone_number, 1, 3 ) = '515' then
aaaray(diff).arac := SUBSTR (i.phone_number, 1, 3 );
aaaray(diff).prf := SUBSTR (i.phone_number, 5, 3 );
aaaray(diff).recnum := SUBSTR (i.phone_number, 9, 4 );
DBMS_OUTPUT.PUT_LINE('phone number is domestic ' || aaaray(diff).arac || aaaray(diff).prf || aaaray(diff).recnum);
INSERT INTO Phonebook VALUES (aaaray(diff).arac, aaaray(diff).prf, aaaray(diff).recnum)) ;
elsif SUBSTR (i.phone_number, 1, 3 ) = '603' then
aaaray(diff).arac := SUBSTR (i.phone_number, 1, 3 );
aaaray(diff).prf := SUBSTR (i.phone_number, 5, 3 );
aaaray(diff).recnum := SUBSTR (i.phone_number, 9, 4 );
DBMS_OUTPUT.PUT_LINE('phone number is domestic ' || aaaray(diff).arac|| aaaray(diff).prf || aaaray(diff).recnum);
INSERT INTO Phonebook VALUES (aaaray(diff).arac, aaaray(diff).prf, aaaray(diff).recnum) ;
else
DBMS_OUTPUT.PUT_LINE('no display');
end if;
end loop;
COMMIT;
END;
/
有一些改变可以简化和加速事情。 具体来说,使用
Phonebook
表本身来定义您的记录,并使用FORALL
语法和基于记录的插入
以下是设置:
CREATE TABLE Phonebook
(
areacode VARCHAR2(3),
prefix VARCHAR2(3),
num VARCHAR2(4)
);
create table Employees
(
employee_id number,
name varchar2(100),
department_id number,
phone_number varchar2(30)
);
insert into employees values(1, 'George Washington', 20, '515-123-4567');
insert into employees values(2, 'Harry Truman', 20, '603-123-4567');
insert into employees values(3, 'Andrew Jackson', 80, '313-123-4567');
insert into employees values(4, 'Millard Fillmore', 90, '011-12-34567890');
commit;
将代码中记录类型的定义替换为对表本身的引用:
-- no need to define the record before, just use phonebook%rowtype
TYPE phonenum IS TABLE OF phonebook%rowtype INDEX BY BINARY_INTEGER;
aaaray phonenum;
aaaray2 phonenum;
修复对记录列的引用以匹配目标表
aaaray(diff).arac := SUBSTR (i.phone_number, 1, 3 );
aaaray(diff).prf := SUBSTR (i.phone_number, 5, 3 );
aaaray(diff).recnum := SUBSTR (i.phone_number, 9, 4 );
...becomes...
aaaray(diff).areacode := SUBSTR (i.phone_number, 1, 3 );
aaaray(diff).prefix := SUBSTR (i.phone_number, 5, 3 );
aaaray(diff).num := SUBSTR (i.phone_number, 9, 4 );
并将INSERT
语句替换为完整记录的FORALL
wrappingINSERT
:
forall i in aaaray.FIRST..aaaray.LAST
insert into Phonebook values aaaray(i);
forall i in aaaray2.FIRST..aaaray2.LAST
insert into Phonebook values aaaray2(i);
FORALL关键字会使Oracle准备好插入的完整列表,然后一次性将它们发送到数据库,而不是对每个记录进行上下文切换。这是更有效的。
因为我们基于表定义了记录,所以可以直接插入它们,而不需要单独引用字段
如果表中有几十个字段,这将使工作变得更加轻松
以下是代码的完整修改版本:
DECLARE
TYPE phonenum IS TABLE OF phonebook%rowtype INDEX BY BINARY_INTEGER;
aaaray phonenum;
aaaray2 phonenum;
CURSOR c IS
SELECT phone_number
from employees
where department_id IN (20,80,90);
diff INTEGER := 0;
BEGIN
for i in c loop
diff := diff + 1;
IF SUBSTR (i.phone_number, 1, 3 ) = '011' then
DBMS_OUTPUT.PUT_LINE('International');
ELSIF SUBSTR (i.phone_number, 1, 3 ) = '515' then
aaaray(diff).areacode := SUBSTR (i.phone_number, 1, 3 );
aaaray(diff).prefix := SUBSTR (i.phone_number, 5, 3 );
aaaray(diff).num := SUBSTR (i.phone_number, 9, 4 );
DBMS_OUTPUT.PUT_LINE('phone number is domestic ' || aaaray(diff).areacode || aaaray(diff).prefix || aaaray(diff).num);
elsif SUBSTR (i.phone_number, 1, 3 ) = '603' then
aaaray2(diff).areacode := SUBSTR (i.phone_number, 1, 3 );
aaaray2(diff).prefix := SUBSTR (i.phone_number, 5, 3 );
aaaray2(diff).num := SUBSTR (i.phone_number, 9, 4 );
DBMS_OUTPUT.PUT_LINE('phone number is domestic ' || aaaray2(diff).areacode|| aaaray2(diff).prefix || aaaray2(diff).num);
else
DBMS_OUTPUT.PUT_LINE('no display');
end if;
end loop;
forall i in aaaray.FIRST..aaaray.LAST
insert into Phonebook values aaaray(i);
forall i in aaaray2.FIRST..aaaray2.LAST
insert into Phonebook values aaaray2(i);
END;
/
DECLARE
TYPE phonenum IS TABLE OF phonebook%rowtype INDEX BY BINARY_INTEGER;
aaaray phonenum;
aaaray2 phonenum;
CURSOR c IS
SELECT phone_number
from employees
where department_id IN (20,80,90);
diff INTEGER := 0;
BEGIN
for i in c loop
diff := diff + 1;
IF SUBSTR (i.phone_number, 1, 3 ) = '011' then
DBMS_OUTPUT.PUT_LINE('International');
ELSIF SUBSTR (i.phone_number, 1, 3 ) = '515' then
aaaray(diff).areacode := SUBSTR (i.phone_number, 1, 3 );
aaaray(diff).prefix := SUBSTR (i.phone_number, 5, 3 );
aaaray(diff).num := SUBSTR (i.phone_number, 9, 4 );
DBMS_OUTPUT.PUT_LINE('phone number is domestic ' || aaaray(diff).areacode || aaaray(diff).prefix || aaaray(diff).num);
elsif SUBSTR (i.phone_number, 1, 3 ) = '603' then
aaaray2(diff).areacode := SUBSTR (i.phone_number, 1, 3 );
aaaray2(diff).prefix := SUBSTR (i.phone_number, 5, 3 );
aaaray2(diff).num := SUBSTR (i.phone_number, 9, 4 );
DBMS_OUTPUT.PUT_LINE('phone number is domestic ' || aaaray2(diff).areacode|| aaaray2(diff).prefix || aaaray2(diff).num);
else
DBMS_OUTPUT.PUT_LINE('no display');
end if;
end loop;
forall i in aaaray.FIRST..aaaray.LAST
insert into Phonebook values aaaray(i);
forall i in aaaray2.FIRST..aaaray2.LAST
insert into Phonebook values aaaray2(i);
END;
/