我有一个使用AJAX的应用程序。我有几个地方正在为用户正在编辑的记录更新单个数据库列。
到目前为止,我一直在为每个AJAX操作创建单独的存储过程...所以我有UPDATE_NAME,UPDATE_ADDRESS,UPDATE_PHONE存储过程。
我只是想知道是否有更好的方法可以继续使用存储过程,但不为每列创建一个。
如果可能的话,我想避免反映指定列的字符串参数。即我知道我可以有一个UPDATE_COLUMN过程,它将列名作为其参数之一。这种方式给了我很多,但如果这是唯一的方法,那么我可以考虑更多。但并非所有列都具有相同的数据类型,因此这看起来不像是一颗银弹。
答案 0 :(得分:3)
考虑编写一个接受多个列的单个更新过程,并对所有非强制列使用DEFAULT NULL
(如其他人所建议的那样)。
在更新中使用NVL
只会更新您提供的列。这种方法的唯一问题是,您无法将值设置为NULL
。
PROCEDURE update_record (
in_id IN your_table.id%TYPE,
in_name IN your_table.name%TYPE DEFAULT NULL,
in_address IN your_table.address%TYPE DEFAULT NULL,
in_phone IN your_table.phone%TYPE DEFAULT NULL,
in_...
) AS
BEGIN
UPDATE your_table
SET name = NVL( in_name, name ),
address = NVL( in_address, address),
phone = NVL( in_phone, phone ),
...
WHERE id = in_id;
END update_record;
您可以使用命名参数调用它:
update_record( in_id => 123, in_address => 'New address' );
这允许您在必要时一次更新多个列。
答案 1 :(得分:1)
我会说停止使用存储过程进行简单的活动,没有理由为数据库中的每一列创建如此多的小程序。你可以用动态sql(带参数)做得更好。
答案 2 :(得分:0)
创建一个可以更新每一列的过程,但只更新传递非空参数的列
CREATE PROCEDURE spUpdateFoo (@fooId INT, @colA INT, @colB VARCHAR(32), @colC float)
AS
update Foo set colA = ISNULL(@colA, colA),
colB = ISNULL(@colB, colB),
colC = ISNULL(@colC, colC)
where fooId = @fooId
请注意,如果您希望能够通过过程显式设置空值,则此方法不起作用,但您可以选择其他值来指定不变(-1等),但复杂性稍高。
答案 3 :(得分:0)
做你正在做的事并没有什么坏处,但是如果你继续这条路,它可能会有点疯狂。您可以做的一件事是创建一个存储过程并将NULL值作为默认参数分配给您要更新的所有字段。因此,当您从应用程序调用sproc时,如果为参数指定了将在更新中使用该值的值,否则该参数将采用空值。
然后你可以检查一下IF @Parameter IS NOT NULL ...
如果您发现自己只需要更新一个字段并且不想创建一个中心sproc并传递空值,那么在我的下方使用Octavia的解决方案并编写一个简单的更新程序。