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
不为空的行),而不仅仅是你期待的那种。
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;
在我的 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
不为空的行),而不仅仅是你期待的那种。
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;