1

我正在尝试移植我在用于 SQL 存储过程的 Java 代码中使用的概念,但我不确定它是否可能。

本质上,如果我有一个包含 10 列的表,我希望每次都能从同一个存储过程中更新不同的列组合。即在Java 中,我将传递一个包含我想要更新的值的映射,并遍历它们并更新缓存中的每个键值。

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

4

2 回答 2

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 中是很难做到的。

于 2013-09-22T02:51:23.367 回答
0

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

如果您可以忍受为每个可能的解决方案制作 IF 语句,那就去做吧——它是稳定、安全和高性能的。

如果您为此设置的参数过多,请使用动态 SQL - 您可以在存储过程或更早的时间生成动态 SQL,但请务必避免SQL 注入问题

您的问题与Erland Sommarskog 所涵盖的动态搜索问题非常相似。

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

这与使用 which 将只有一个执行计划形成鲜明对比COLUMNB = CASE WHEN @COLUMNB IS NULL THEN COLUMNB ELSE @COLUMNB END,因此通常执行计划很差(取决于数据库中的 where 子句和索引)和性能差。

于 2013-09-22T11:13:54.170 回答