【问题标题】:How to invoke TSQL statement with params?如何使用参数调用 TSQL 语句?
【发布时间】:2020-11-06 18:41:50
【问题描述】:

如何在 tsql 中使用参数,或者在合并语句中重新使用这些值,而不必多次传递这些值?我做错了什么?

使用参数运行 TSQL 会引发以下异常

变量名“@p1”已被声明。变量名必须 在查询批处理或存储过程中是唯一的。”

以表def为例:

dbo.Test
(
[key]      VarChar(50),
[value]    VarChar(50)
)

示例 Java 代码:

try (PreparedStatement s = conn.prepareStatement("DECLARE @p1 VarChar(50) DECLARE @p2 VarChar(50) SET @p1 = ? SET @p2 = ? INSERT dbo.Test ([key], [value]) values(@p1, @p2)"))
{
    s.setString(1,"Hello");
    s.setString(2,"World");
    s.execute();
}

在下面也尝试了相同的结果

DECLARE @p1 VarChar(50) = ?
DECLARE @p2 VarChar(50) = ?

编辑: 上面的代码只是一个示例,我需要/想要使用参数,因此我不必多次设置相同的值以在Merge Statement中使用

dbo.Test 的合并语句如下所示:

DECLARE @key    VarChar(50)
DECLARE @val    VarChar(50)

MERGE dbo.Test t
USING (SELECT @key [k]) s
    ON t.[key] = s.k
WHEN MATCHED THEN
    UPDATE
    SET t.[value] = @val
WHEN NOT MATCHED THEN
    INSERT ([key], [value])
    VALUES (@key, @val);

我宁愿不必一次又一次地设置相同的值

【问题讨论】:

标签: java sql-server tsql jdbc mssql-jdbc


【解决方案1】:

不要使用 TSQL 变量,直接插入值即可。

String sql = "INSERT INTO dbo.Test ([key], [value]) VALUES (?, ?)";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
    stmt.setString(1, "Hello");
    stmt.setString(2, "World");
    stmt.executeUpdate();
}

UPDATE使用MERGE进行问题编辑:

上面的代码只是一个示例,我需要/想要使用参数,所以我不必多次设置相同的值以用于Merge Statement

如果您按照该链接中显示的示例进行操作,您将看到每个变量只使用一次,因此从 Java 执行时根本没有理由需要变量。

Example A来自链接:

MERGE Production.UnitMeasure AS target  
USING (SELECT @UnitMeasureCode, @Name) AS source (UnitMeasureCode, Name)  
ON (target.UnitMeasureCode = source.UnitMeasureCode)  
WHEN MATCHED THEN
    UPDATE SET Name = source.Name  
WHEN NOT MATCHED THEN  
    INSERT (UnitMeasureCode, Name)  
    VALUES (source.UnitMeasureCode, source.Name)  
OUTPUT deleted.*, $action, inserted.* INTO #MyTempTable;  

应用于问题的陈述:

String sql = "MERGE dbo.Test AS t" +
            " USING (SELECT ?, ?) AS s (k, v)" +
               " ON t.[key] = s.k" +
             " WHEN MATCHED THEN" +
                 " UPDATE SET [value] = s.v" +
             " WHEN NOT MATCHED THEN" +
                 " INSERT ([key], [value])" +
                 " VALUES (s.k, s.v)";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
    stmt.setString(1, "Hello"); // s.k
    stmt.setString(2, "World"); // s.v
    stmt.executeUpdate();
}

【讨论】:

  • 是的,如果我不必重用这些值,我会立即执行此操作。我需要使用参数不要一遍又一遍地重复设置相同的值。查看更新
  • 当然!为什么我没有想到使用别名....smh :) 非常感谢,这应该可以解决问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多