【问题标题】:use sql command more than once with different commands使用不同的命令多次使用 sql 命令
【发布时间】:2011-07-24 21:00:37
【问题描述】:

我一直在尝试使用相同的 SqlConnectionSqlCommand 对象来执行不同的命令。

第一个检查重复,如果用户输入的数据不重复,第二个插入数据。

这是我的代码示例:

        using (SqlConnection conn = new SqlConnection(ConnStr))
        {
            string Command = "SELECT CountryName FROM [Countries] WHERE CountryName = @Name";

            using (SqlCommand comm = new SqlCommand(Command, conn))
            {
                comm.Parameters.Add("@Name", System.Data.SqlDbType.NVarChar, 20);
                comm.Parameters["@Name"].Value = Name;

                comm.Parameters.Add("@IsVisible", System.Data.SqlDbType.Bit);
                comm.Parameters["@IsVisible"].Value = IsVisible;

                conn.Open();

                if (comm.ExecuteScalar() == null)
                {
                        Command = "INSERT INTO [Countries] (CountryName, IsVisible) VALUES (@Name, @IsVisible);";
                        comm.ExecuteNonQuery();
                }
        }

我试图通过使用一个连接来保存对数据库的访问。

问题是:

第一个命令运行正常,但是 第二个命令插入 数据库不起作用(它不添加 数据库的任何记录),当我 试图显示影响它的行 给了我-1!!

问题是:

这是检查的理想方法吗? 约束 a 的重复记录 独特的国家?以及为什么第二个 命令没有执行?

【问题讨论】:

  • 您不需要明确需要使用相同的数据库连接来保存到数据库的行程,因为connection pooling 几乎肯定会被使用(除非您已经明确禁用它)。如果执行两次(使用或不使用相同的连接),将会有两次调用 DB。
  • 感谢您的提示 +1 .. 但在您看来,在我的情况下,您是否认为有一种方法可以减少 Db 的负载?
  • 如果您使用存储过程,绝对可以。这会是一个选择吗?
  • @IKashef:我的回答中描述的方式(在列上放置数据库约束并在重复的情况下处理抛出的异常)只需要一次访问数据库。
  • @steinar,这是一个选项,但您有存储过程的代码吗? ..我的意思是我尝试选择后如何检查名称是否存在!?

标签: c# asp.net sql ado.net


【解决方案1】:

您正在更改string Command 的值,但实际上从未更改SqlCommand comm 中的命令字符串。

【讨论】:

    【解决方案2】:

    当您使用插入语句重写Command 变量时,您只是在修改您之前定义的名为Command 的字符串。您没有修改存储在 SqlCommand 对象中的命令文本。

    试试:

    comm.CommandText = "INSERT INTO [Countries] (CountryName, IsVisible) VALUES (@Name, @IsVisible);";

    【讨论】:

    • 这很简单.. 谢谢 =)
    【解决方案3】:

    回答您的第一个问题:不,这不是确保国家名称唯一性的方法。在您的数据库中,您应该定义您的国家表,以便 CountryName 是主键(或者,您可以将其他一些列声明为 PK 并在 CountryName 上定义唯一约束)。

    然后,尝试插入重复值将引发异常,您可以适当处理(丢弃现有记录、覆盖它、提示用户输入不同的值等)。

    通过您的方法检查唯一性被认为是不好的,因为 A) 它将属于数据库本身的逻辑放入您的应用程序代码中; B)它引入了潜在的竞争条件,其中一些其他应用程序或线程在您读取数据库和写入数据库之间插入一个值。

    【讨论】:

    • +1 .. 我希望我也可以将此标记为答案.. 但我最初的问题是“为什么我没有得到预期的输出”.. 但我认为你真的是对的关于处理异常。尽管数字 B 对我来说有点时尚! =)
    • @IKashef:B 比较少见,尽管在许多不同线程同时访问数据库的环境中,这种情况经常发生,足以让您丢掉工作。 :) 这些年来,我继承了许多其他人编写的应用程序/数据库,并且在开发人员依靠他的应用程序代码来确保唯一性的每一种情况下,表中都有大量重复项。这是一种保证最终不会奏效的方法。
    • 你刚刚救了我! .. 因为我的应用程序允许不止一个人添加东西,有时我们需要所有团队都输入数据! .. 非常感谢,如果您有任何文章可以在同时操作或访问数据库时避免此问题,请发布..+1
    • 这些家伙非常适合 ASP.NET:aspnet.4guysfromrolla.com/default.aspx
    • 我不确定这是否合适,但如果您有时间查看此相关问题stackoverflow.com/questions/5466771/…,我将不胜感激。 =) 再次感谢!
    【解决方案4】:

    我建议将插入与您的选择语句分开.. 有点像:

        private void Insert()
        {
            using (SqlConnection conn = new SqlConnection(ConnStr)) 
             {             
            string Command = "INSERT INTO [Countries] (CountryName, IsVisible) VALUES (@Name, @IsVisible)";    
    
            using (SqlCommand comm = new SqlCommand(Command, conn)) 
             {
            comm.Parameters.Add("@Name", System.Data.SqlDbType.NVarChar, 20); 
            comm.Parameters["@Name"].Value = Name;
            comm.Parameters.Add("@IsVisible", System.Data.SqlDbType.Bit);                 comm.Parameters["@IsVisible"].Value = IsVisible;
            conn.Open(); 
    
            comm.ExecuteNonQuery();
    
            conn.Close();
            } 
    
    }
    

    private void SelectInsert()
    {
          using (SqlConnection conn = new SqlConnection(ConnStr)) 
         {             
        string Command = "SELECT CountryName FROM [Countries] WHERE CountryName = @Name";              
        using (SqlCommand comm = new SqlCommand(Command, conn)) 
         {
        comm.Parameters.Add("@Name", System.Data.SqlDbType.NVarChar, 20); 
        comm.Parameters["@Name"].Value = Name;
    
        conn.Open(); 
        if (comm.ExecuteScalar() == null)
        { 
    
               Insert(); //your save method
    
         }
        } 
    }
    

    问候

    【讨论】:

    • 感谢您抽出宝贵时间 :) .. 但更改 CommandText 就成功了! =)
    猜你喜欢
    • 2015-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-11
    相关资源
    最近更新 更多