1

下面是我的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: too many values

就我而言,我不需要在RECORDTYPE 上声明所有列,因此尝试减少RECORD TYPE声明中的列数。这种行为有什么具体原因吗?

4

2 回答 2

3

您不能ROW使用记录使用关键字更新实际行。

文档

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

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

于 2013-06-16T11:02:32.927 回答
2

不能期望 Oracle 知道您在记录类型中遗漏了哪些列,因此它也无法知道映射记录字段的表列。

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

在某些情况下,Oracle可能会猜测或假设您的意图,但这意味着它必须做更多的工作,在不同的情况下会有不同的行为,也许更重要的是依赖这些假设可能意味着它会结束up 实际上没有按照你的意思做,这对你的代码来说是危险的。

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

update emp
set empname = 'Alen', empdept = 2
where empid = 11;
于 2013-06-16T11:02:47.523 回答