【问题标题】:IF NOT EXISTS working in query mode but not working properly in stored procedure call from codeIF NOT EXISTS 在查询模式下工作,但在代码的存储过程调用中无法正常工作
【发布时间】:2021-06-25 08:14:54
【问题描述】:

我有一个执行如下操作的存储过程:

MY_STORED_PROCEDURE:

IF NOT EXISTS(SELECT 1 FROM MY_TABLE WHERE MY_COLUMN1 = @MY_COLUMN1_VALUE_FROM_CODE AND MY_COLUMN2 = @MY_COLUMN2_VALUE_FROM_CODE)
BEGIN
   --INSERT INTO MY_TABLE

这个存储过程是从 C# 代码中自动调用的。

现在,这意味着:

  1. 如果我们尝试为 COLUMN1 和 COLUMN2 组合插入一个带有 NEW VALUES 的条目,那么它应该被插入到 MY_TABLE 中。

  1. 如果我们尝试为 COLUMN1 和 COLUMN2 组合插入一个具有 EXISTING VALUES 的条目,则不应将其插入 MY_TABLE。

但是,发生的情况是插入一直在发生,与“IF NOT EXISTS”语句无关。

我已经直接从 SSMS 的查询构建器中检查了“IF NOT EXISTS”语句,该语句似乎没有任何问题。

有什么我没有考虑到的吗?这可能是什么错误?

这也是我调用我的 SP 的 C# 代码:

public void InsertIntoMyTable(List<SqlParameter> parameters, SqlConnection connection)
{
   DataTable dt = new DataTable();

   SqlCommand command = new SqlCommand("MY_STORED_PROCEDURE", connection)
   {
      CommandType = CommandType.StoredProcedure
   };
   if (parameters != null)
   {
      foreach (SqlParameter parameter in parameters)
      {
         command.Parameters.Add(parameter);
      }
   }
   dt.Load(command.ExecuteReader());
}

注意:MY_STORED_PROCEDURE 是从不同的来源调用的。因此,也有可能同时从 1 个以上的源调用此过程。我不知道这是否会对我的问题产生一些影响。我正在报告它,以防万一。

谢谢!

【问题讨论】:

  • 为什么不将您的条件放在where 子句中而不是if 语句中?但是,如果它适用于 SSMS 而不是 C#,那么您将发送不同的值……就这么简单。您需要仔细检查您的 C# 代码和传入的值。实际上您应该在此处发布您的 C# 代码。
  • 我添加了负责调用 MY_STORED_PROCEDURE 的 C# 代码
  • 是的,如果您可以同时从不同的来源调用相同的过程,那么该行为当然可能是出乎意料的,因为您没有任何并发​​处理。
  • 不,ExecuteReader 不会改变 SP 的运行方式。您需要发布参数的确切值和数据类型...因为问题必须就在那里 - 这是与 SSMS 唯一不同的地方。
  • 同意@DaleK,你应该展示分配参数的真实代码,因为它们可能没有得到正确的类型或值。

标签: sql sql-server tsql stored-procedures transactions


【解决方案1】:

首先,`NOT EXISTS* 是错误的做法,因为它引入了竞争条件。您似乎想要的是一个独特的约束。因此,将其添加为约束或索引,然后检查错误:

alter table t add constraint unq_my_table_column1_column2 on my_table (column1, column2);

然后只需执行 insert 即可。 . .但在TRY/CATCH 块中:

begin try
    insert into my_table ( . . . )
        values ( . . .);
end try;
begin catch
    . . . 
end catch;

如果我必须推测问题,那么您的参数有问题。也许它们被错误地声明了——比如varchar()没有长度。或者它们可能被错误地传递,如NULLs。

【讨论】:

    【解决方案2】:

    前段时间我也发生过类似的事情,因为我没有在存储过程的开头添加SET NOCOUNT ON;

    【讨论】:

    • 不是答案...适合发表评论。
    • 如果 SP 在 SSMS 而非 C# 中工作,您可以确定 SP 是正常的。
    • 我在我的 SP 中设置了 NOCOUNT
    • 与 ADO 经典不同,ADO.NET 不需要 SET NOCOUNT ON
    猜你喜欢
    • 2017-06-06
    • 2014-12-09
    • 2017-03-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-26
    • 1970-01-01
    • 2022-01-01
    • 2016-10-06
    相关资源
    最近更新 更多