Oracle 10g中的记录类型太多值错误

时间:2013-06-16 09:47:10

标签: sql database oracle plsql oracle10g

以下是我的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声明中的列数。这种行为的任何具体原因?

2 个答案:

答案 0 :(得分:3)

您无法使用记录更新ROW关键字的行。

来自docs

  

使用PL / SQL记录值更新数据库

     

UPDATE语句的PL / SQL-only扩展允许您更新   使用RECORD类型或%ROWTYPE on的单个变量的数据库行   SET子句的右侧,而不是字段列表。

答案 1 :(得分:2)

不能指望Oracle知道您从记录类型中省略了哪些列,因此无法知道哪个列也会映射记录字段。

您可能会认为应该能够解决这个问题,因为您在记录定义中使用了%type。但这只是在更一般的结构中使这成为一个特例。您可以使用显式类型,例如varchar2number,或不同的源表格,例如dept.dept_id%type,它仍然可以在所有列都已“映射”的第一个实例中运行;但在第二种情况下,不可能知道列到字段的关系。

可能可能让Oracle猜测或假设你在某些案例中的意图,但这意味着它必须做更多的工作,行为会有所不同在不同的情况下,也许更重要的是依赖于这些假设可能意味着它最终并没有真​​正按照你的意思行事,这对你的代码来说是危险的。

如果你真的想使用ROW选项,你可以声明其他字段,但是使用null或其他默认值;但那会用你的默认值覆盖任何现有的列值,这可能不是你想要的。或者在记录中选择现有值。否则,您必须在update中单独指定colmns,这更为正常。我不确定你为什么要在这里使用记录,而不是简单update设置你直接关注的两列:

update emp
set empname = 'Alen', empdept = 2
where empid = 11;