以下是我的emp
表的结构:
Name Null? Type
------------------ -------- ------------
EMP_ID NOT NULL NUMBER
EMP_NAME VARCHAR2(20)
DEPT_ID NUMBER
AGE NUMBER
SEX VARCHAR2(5)
如果我使用下面的RECORD TYPE
定义,那么它可以工作:
declare
type rec_emp is record(empid emp.emp_id%TYPE, empname emp.emp_name%type, empdept emp.dept_id%type, empage emp.age%type, empsex emp.sex%type);
v_emprecord rec_emp;
begin
v_emprecord.empid := 11;
v_emprecord.empname := 'Alen';
v_emprecord.empdept := 2;
v_emprecord.empage := 27;
v_emprecord.empsex := 'M';
update emp set ROW = v_emprecord where emp_id = 11;
dbms_output.put_line('Rows Updated: ' || sql%rowcount);
end;
但是,如果我尝试这个代码然后它不起作用(这里我减少了RECORD TYPE
变量中的列数):
declare
type rec_emp is record(empname emp.emp_name%type, empdept emp.dept_id%type);
v_emprecord rec_emp;
begin
v_emprecord.empname := 'Alen';
v_emprecord.empdept := 2;
update emp set ROW = v_emprecord where emp_id = 11;
dbms_output.put_line('Rows Updated: ' || sql%rowcount);
end;
错误是:PL / SQL:ORA-00913:值太多
就我而言,我不需要在RECORD
TYPE上声明所有列,因此尝试减少RECORD TYPE
声明中的列数。这种行为的任何具体原因?
答案 0 :(得分:3)
您无法使用记录更新ROW
关键字的行。
来自docs
使用PL / SQL记录值更新数据库
UPDATE语句的PL / SQL-only扩展允许您更新 使用RECORD类型或%ROWTYPE on的单个变量的数据库行 SET子句的右侧,而不是字段列表。
答案 1 :(得分:2)
不能指望Oracle知道您从记录类型中省略了哪些列,因此无法知道哪个列也会映射记录字段。
您可能会认为应该能够解决这个问题,因为您在记录定义中使用了%type
。但这只是在更一般的结构中使这成为一个特例。您可以使用显式类型,例如varchar2
和number
,或不同的源表格,例如dept.dept_id%type
,它仍然可以在所有列都已“映射”的第一个实例中运行;但在第二种情况下,不可能知道列到字段的关系。
可能可能让Oracle猜测或假设你在某些案例中的意图,但这意味着它必须做更多的工作,行为会有所不同在不同的情况下,也许更重要的是依赖于这些假设可能意味着它最终并没有真正按照你的意思行事,这对你的代码来说是危险的。
如果你真的想使用ROW
选项,你可以声明其他字段,但是使用null或其他默认值;但那会用你的默认值覆盖任何现有的列值,这可能不是你想要的。或者在记录中选择现有值。否则,您必须在update
中单独指定colmns,这更为正常。我不确定你为什么要在这里使用记录,而不是简单update
设置你直接关注的两列:
update emp
set empname = 'Alen', empdept = 2
where empid = 11;