[英]How to pass column name as parameter in a Stored Procedure in PL/SQL?
[英]PL/SQL stored procedure to update values of a column that is specified by the parameter
我正在尝试在 PL/SQL 中创建一个存储过程,它可以通过采用 3 个参数来更新值
如何在不重复重写 set/update 语句的情况下实现这一点?
此代码不起作用:
CREATE OR REPLACE PROCEDURE dp_replace_values (
old_value varchar2, new_value varchar2, column_name varchar2
) IS
BEGIN
UPDATE dp_mock_data
SET
first_name = case when column_name = 'first_name' then old_value end,
last_name = case when column_name = 'last_name' then new_value end
WHERE
last_name = old_value;
END dp_replace_values;
下面的代码确实有效,但它不断重复更新和设置语句。
CREATE OR REPLACE PROCEDURE dp_replace_values (
old_value varchar2, new_value varchar2, column_name varchar2
) IS
BEGIN
IF column_name = 'first_name' then
UPDATE dp_mock_data
SET
first_name = new_value
WHERE
first_name = old_value;
ELSIF column_name = 'last_name' then
UPDATE dp_mock_data
SET
last_name = new_value
WHERE
last_name = old_value;
end if;
END dp_replace_values;
您必须使用动态 SQL。
CREATE OR REPLACE PROCEDURE dp_replace_values (
old_value varchar2,
new_value varchar2,
column_name varchar2
)
IS
BEGIN
EXECUTE IMMEDIATE 'UPDATE dp_mock_data ' ||
' SET ' || column_name || ' = :1 '
' WHERE ' || column_name || ' = :2 '
USING new_value, old_value;
END;
实际上,您需要添加逻辑来防止 SQL 注入。 至少,使用dbms_assert
来验证column_name
是 SQL 标识符。 但可能更多——我想查询all_tab_columns
以确认column_name
实际上是dp_mock_data
表中列的名称。 如果您的系统碰巧使用任何区分大小写的列名,则需要添加代码。 您需要添加代码来记录在执行之前生成的语句,以便进行调试。
如果你走动态 SQL 路线,你会更难维护代码。 你把很多编译错误变成了运行时错误。 你使调试变得更加困难。 您消除了使用数据库的数据字典查找对象之间依赖关系的能力。 而且收益往往不是特别大。 通常很容易为每一列创建一个update
过程,或者创建一个允许您更新一个或多个列并保持其他列不变的过程。 而且您通常希望在进行更新时指定一个键,而不是使用相同的old_value
更新每一行(如果可能是多行,我怀疑您想要规范化您的数据模型并只更新查找表)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.