Oracle:从过程中更新不起作用

Oracle: Update from within procedure not working

在我的 Oracle PL/SQL 过程中,我尝试更新这样一行:

UPDATE personal p
SET p.surname = surname, p.name = name, p."alter" = alter, p.sex = sex, p.jobcode = jobcode, p.year_wage = month_wage * 12
WHERE p.personalnr = personalnr;
COMMIT;

我在提交后立即添加了这两个语句,以确认代码已到达并使用正确的参数执行(例如,这里我想更改名称):

DBMS_OUTPUT.put_line('updated ' || name);
DBMS_OUTPUT.put_line('personalnr ' || personalnr);

现在这个更新语句是从另一个过程中调用的过程的一部分。

但是,不会应用更改,即使执行了更新,名称也将保持不变。我也尝试过使用异常处理程序,但似乎没有发生任何异常。我可以确认 WHERE 子句符合预期。有一条记录符合谓词。

奇怪的是: 当我将代码更改为下面的示例时,会发生更新。但是,它会更新 条记录,而不仅仅是具有正确 personalnr 的记录。再次说明:该例程仅被调用一次,其中一个 personalnr 仅匹配 table.

中的一个条目
UPDATE personal p
SET p.name = 'test'
WHERE p.personalnr = personalnr;
COMMIT;

您需要更改参数名称,而不是 table 的列名称。

UPDATE personal p
SET p.name = 'test'
WHERE p.personalnr = personally; 
-- here condition is column_name = column_name
-- This will be true for all the records of the table

更改 personalnr --> p_personalnr 它会为你工作

它正在工作,但它正在更新 table 中的 所有 行(或者至少,那些 personalnr 不为空的行),而不仅仅是你期待的那种。

From the documentation:

If a SQL statement references a name that belongs to both a column and either a local variable or formal parameter, then the column name takes precedence.

您有一个与列同名的 PL/SQL 变量。当你这样做时

where p.personalnr = personalnr

你真的在做:

where p.personalnr = p.personalnr

同样的事情发生在 set 部分; SET p.surname = surname 将列值更新为它之前的任何值,而不是 PL/SQL 变量的值。所以它看起来好像更新没有发生——它实际上发生了,但因为一切都设置为与它的原始值相同,所以看起来好像没有发生任何事情。 (除了 - 所有行现在都将具有相同的 year_wage 值...)

您可以在变量前加上过程名称:

where p.personalnr = my_proc.personalnr

或更改变量名称,使其不冲突;通常使用短前缀,例如l_ 为局部变量,或 p_ 为传入参数,等等

where p.personalnr = l_personalnr

记得对 set 部分也这样做,否则您的更新似乎仍然不会执行任何操作。

UPDATE personal p
SET p.surname = l_surname, p.name = l_name, p."alter" = l_alter,
  p.sex = l_sex, p.jobcode = l_jobcode, p.year_wage = l_month_wage * 12
WHERE p.personalnr = l_personalnr;