更新存储过程中的不同列

时间:2013-09-22 02:19:13

标签: mysql sql sql-server postgresql stored-procedures

我正在尝试移植我在Java代码中使用的概念,我已经习惯了SQL存储过程,我不确定它是否可行。

基本上,如果我有一个包含10列的表,我希望每次都能够从同一存储过程更新不同的列组合。即在Java中,我会传递一个包含我想要更新的值的地图,并迭代它们并更新缓存中的每个键值。

这样做的好处是不必更改方法签名以包含每个列名,也不必让大块代码对每个变量进行空检查,以确定是否应该更新它。我不确定这是否可能,或者某些数据库服务器是否具备它(即PostgreSQL,Oracle,MySQL),或者他们都能够做到这一点,但我无法弄清楚语法。

2 个答案:

答案 0 :(得分:1)

在SQL Server中,以下过程可以使用如下表格:

CREATE TABLE MyBigTable(
    ID INT NOT NULL PRIMARY KEY,
    COLUMNA VARCHAR(100) NOT NULL,
    COLUMNB VARCHAR(100) NOT NULL
 )

GO

CREATE PROCEDURE UpdateMyBigTable(@ID INT, @ColumnAValue VARCHAR(100)=NULL, @ColumnBValue VARCHAR(100)=NULL)
AS BEGIN
UPDATE MyBigTable
    SET COLUMNA = CASE WHEN @ColumnAValue IS NULL THEN COLUMNA ELSE @ColumnAValue END,
    COLUMNB = CASE WHEN @ColumnBValue IS NULL THEN COLUMNB ELSE @ColumnBValue END
WHERE ID = @ID
    AND ((COLUMNA <> @ColumnAValue AND @ColumnAValue IS NOT NULL) OR (COLUMNB <> @ColumnBValue AND @ColumnBValue IS NOT NULL));
END

GO

但是,这实际上并不是通过您所询问的字段进行枚举。如果没有进入动态SQL,这在SQL Server中很难做到。

答案 1 :(得分:0)

为获得最佳性能,请为每个可能的查询参数组合使用动态SQL或带有SQL语句的IF语句。

如果您可以为每个可能的解决方案制作IF语句,那么请使用它 - 它稳定,安全且高效。

如果您有太多参数,请使用动态SQL - 您可以在存储过程中或之前生成动态SQL,只需确保避免使用SQL injection issues

您的问题与Erland Sommarskog所涵盖的dynamic search问题非常相似。

性能方面,SQL Server将为每种可能的动态查询类型创建执行计划,因此性能与使用IF语句选择每个可能的SQL语句一样好。

这与使用COLUMNB = CASE WHEN @COLUMNB IS NULL THEN COLUMNB ELSE @COLUMNB END形成鲜明对比,{{1}}只有一个执行计划,因此经常是一个糟糕的执行计划(取决于你的where子句和数据库中的索引)和性能不佳。