【问题标题】:SQL C# Check if record exists, if exists deleteSQL C# 检查记录是否存在,如果存在则删除
【发布时间】:2016-08-16 15:27:16
【问题描述】:

使用存储过程尝试检查记录是否存在,如果存在,则应通过删除并给出适当的消息来进行检查,如果不存在则发送另一条消息。这是我的 C# 代码。

protected void deleteButton_Click(object sender, EventArgs e)
{
    int deletedCustomers;

    if (String.IsNullOrEmpty(txtCustID.Text))
    {
        lblError.Text = "Please enter a valid Customer ID";
        return;
    }
    else
    {
       dynamic procedure = "dbo.deleteCustomer";

       using (command = new SqlCommand(procedure, conn))
       {
           command.CommandType = CommandType.StoredProcedure;
           command.Parameters.AddWithValue("@CustID", txtCustID.Text);
       }

       try
       {
           conn.Open();
           command.ExecuteNonQuery();
           deletedCustomers = command.ExecuteNonQuery();

           if (deletedCustomers > 0) {
               lblError.Text = "Deleted!";   
           }
           else
           {
               lblError.Text = "Customer ID does not exist";
           }

           conn.Close();              
       }
       catch (Exception ex)
       {
           lblError.Text = "Error: " + ex.Message;
           conn.Close();
       }
    }
}

这是我的 SQL Server 存储过程:

CREATE PROCEDURE [dbo].[deleteCustomer]
     @CustID INT
AS
     DELETE FROM [dbo].[Customer]
     WHERE CustID = @CustID

运行此代码会根据需要删除记录,但不会输出正确的标签,当我尝试删除不存在或存在的记录时,它会给我“不存在”文本输出而不是“ Deleted' IF 语句中的文本输出。

我需要在 IF 语句中进行哪些更改才能使其看到 command.ExecuteNonQuery 等于或不等于任何值,这样我才能让它显示正确的输出?谢谢。

【问题讨论】:

  • 你的 using 语句看起来很奇怪,它可能会把事情搞砸。看看:msdn.microsoft.com/sv-SE/library/yh598w02.aspx
  • 对了,你为什么用command.ExecuteNonQuery两次?
  • @mmushtaq - 绝对确定它已被删除 :-)
  • @mmushtaq - 成功了。无论第一次调用它是否存在,第二次肯定不会存在,因此代码正确反映了这一点。

标签: c# sql sql-server


【解决方案1】:

另外,如果你仔细阅读MSDN documentation on ExecuteNonQuery你会发现:

对于 UPDATE、INSERT 和 DELETE 语句,返回值为 受命令影响的行数。当触发器存在于 正在插入或更新的表,返回值包括数字 受插入或更新操作和数量影响的行数 受触发器或触发器影响的行数。对于所有其他类型的 语句,返回值为-1。如果发生回滚,则返回 值也是-1。

未列出存储过程。添加select @@ROWCOUNT(参见@mmushtaq 答案)或使用DELETE FROM [dbo].[Customer] WHERE CustID = @CustID 代替程序。最后:您真的需要此类查询的程序吗?

【讨论】:

  • 我过去确实见过一些例子,如果存储过程中的第一个语句是上述语句之一,它确实会返回行数,尽管文档似乎不支持这种解释。 mmushtaq 在 cmets 中指出的双重调用意味着它是否(将)通过存储过程工作并不重要。
  • 需要是存储过程。
【解决方案2】:

你需要得到@@ROWCOUNT如下:

CREATE PROCEDURE [dbo].[deleteCustomer]
@CustID INT
AS
DELETE FROM [dbo].[Customer]
WHERE CustID = @CustID
select @@ROWCOUNT

它将返回 No of effective rows

删除此语句

command.ExecuteNonQuery();

就用这个

 deletedCustomers = command.ExecuteScalar();

编辑

try
       {
           conn.Open();

           deletedCustomers = command.ExecuteScalar();

           if (deletedCustomers > 0) {
               lblError.Text = "Deleted!";   
           }
           else
           {
               lblError.Text = "Customer ID does not exist";
           }

           conn.Close();              
       }

【讨论】:

  • 我将 select @@ROWCOUNT 添加到我的删除客户程序中。我仍然从我的 IF 语句中得到错误的输出。
  • @Minosum - 如果你想走 @@ROWCOUNT 路线,你还需要切换到 ExecuteScalar 以读取值 - 但你是否尝试过减少对 @987654328 的双重调用在 cmets 中指出的 @ 并保持其余代码相同?
  • 对不起,我是新手,不知道我在哪里调用它两次?
  • @Minosum - 查看您的代码。在您正在查看的任何编辑器中,我确信有一个 FindSearch 函数。尝试找到ExecuteNonQuery。您会发现您在连续的行中调用了两次(除非您向我们展示的代码与您的实际代码完全不同,已经有一些迹象表明,但在这种情况下,您只是在制作它我们很难通过不向我们展示实际代码来帮助您)
  • 谢谢大家,我刚刚删除了额外的executenonQuery,并添加了command.executeScalar 以等于deletedcustomer int 变量,似乎正在工作,感谢大家的帮助:)
【解决方案3】:

在大多数情况下,command.ExecuteNonQ‌​uery 返回 -1 作为返回值

对于 UPDATE、INSERT 和 DELETE 语句,返回值为 受命令影响的行数。当触发器存在于 正在插入或更新的表,返回值包括数字 受插入或更新操作和数量影响的行数 受触发器或触发器影响的行数。对于所有其他类型的 语句,返回值为-1。如果发生回滚,则返回 值也是-1。

按照其他帖子中的建议,您需要获取@@ROWCOUNT

更多详情请参考链接https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executenonquery(v=vs.110).aspx

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-29
    • 1970-01-01
    • 2012-10-09
    • 1970-01-01
    • 2018-03-31
    • 2019-10-13
    相关资源
    最近更新 更多