我正在尝试创建一个PL / SQL程序,在该程序中我向表中添加一列(称为AGE_GROUP),然后将数据插入该列中,但它似乎不起作用。
DECLARE
cust_age string(10);
cust_inc string(10);
cust_status string(10);
BEGIN
EXECUTE IMMEDIATE 'ALTER TABLE DATACOPY ADD(AGE_GROUP VARCHAR2(10));';
FOR emp IN (SELECT *
FROM datacopy) LOOP
cust_age := get_group_age(emp.ID);
cust_inc := get_income_level(emp.ID);
cust_status := fix_status(emp.ID);
UPDATE datacopy SET AGE_GROUP = cust_age WHERE ID = emp.ID;
UPDATE datacopy SET INCOME_LEVEL = cust_inc WHERE ID = emp.ID;
UPDATE datacopy SET MARITAL_STATUS = cust_status WHERE ID = emp.ID;
COMMIT;
END LOOP;
END;
我看到的错误是错误报告- ORA-06550:第12行,第27列: PL / SQL:ORA-00904:“ AGE_GROUP”:不可接受的标识符
答案 0 :(得分:3)
正如@Maxim所说,在解析PL / SQL块时,表中没有AGE_GROUP
列,因此
UPDATE datacopy SET AGE_GROUP = cust_age WHERE ID = emp.ID;
引发您看到的ORA-00904错误。您还必须使该更新语句动态化,例如:
EXECUTE IMMEDIATE 'UPDATE datacopy SET AGE_GROUP = :1 WHERE ID = :2' USING cust_age, emp.ID;
但是您的游标查询也会遇到问题,因为在运行时,它不再与编译时的表定义匹配-因此SELECT *
现在返回的列比预期的多。 (由此产生的错误是ORA-00932。)
您可以使整个光标循环动态化,但是由于仅使用ID列,因此不需要-只需选择该特定列即可,而不是选择*
。当然,您应该只在所有代码中选择想要的列。
因此,要使其正常工作,您可以:
DECLARE
cust_age string(10);
cust_inc string(10);
cust_status string(10);
BEGIN
EXECUTE IMMEDIATE 'ALTER TABLE DATACOPY ADD(AGE_GROUP VARCHAR2(10))';
FOR emp IN (SELECT ID
FROM datacopy) LOOP
cust_age := get_group_age(emp.ID);
cust_inc := get_income_level(emp.ID);
cust_status := fix_status(emp.ID);
EXECUTE IMMEDIATE 'UPDATE datacopy SET AGE_GROUP = :cust_age WHERE ID = :id'
USING cust_age, emp.ID;
UPDATE datacopy SET INCOME_LEVEL = cust_inc WHERE ID = emp.ID;
UPDATE datacopy SET MARITAL_STATUS = cust_status WHERE ID = emp.ID;
COMMIT;
END LOOP;
END;
/
尽管此代码还有很多其他问题。使用string(10)
作为局部变量的数据类型不是Oracle-y,并且它们实际上并不是全部都是字符串-您可以将%TYPE
用于表中已经存在的列。您不应该在循环内提交。当您可以一次设置所有三个列的值时,只需使用一条动态语句,就可以对同一行进行三个单独的更新,这似乎很浪费:
EXECUTE IMMEDIATE 'UPDATE datacopy SET AGE_GROUP = :cust_age,'
|| ' INCOME_LEVEL = :cust_inc,'
|| ' MARITAL_STATUS = :cust_status'
|| ' WHERE ID = :id'
USING cust_age, cust_inc, cust_status, emp.ID;
当然,将ALTER
作为一个简单的SQL语句(而不是在PL / SQL块之前)做起来要简单得多,
看起来您似乎根本就不需要PL / SQL,也不是逐行循环;您可以在进行静态更改后进行一次静态更新:
ALTER TABLE DATACOPY ADD(AGE_GROUP VARCHAR2(10));
UPDATE datacopy SET AGE_GROUP = get_group_age(ID),
INCOME_LEVEL = get_income_level(ID),
MARITAL_STATUS = fix_status(ID);
答案 1 :(得分:1)
这是因为首先解析该块,然后在没有错误的情况下才执行该块。因为在解析时datacopy表中没有age_group列,所以您会得到解析错误。您应该尝试使用动态SQL,引用游标。
并删除其中一个冒号,应为以下内容:
EXECUTE IMMEDIATE 'ALTER TABLE DATACOPY ADD(AGE_GROUP VARCHAR2(10))';