【问题标题】:How to run multiple SQL commands in a single SQL connection?如何在单个 SQL 连接中运行多个 SQL 命令?
【发布时间】:2012-11-20 13:38:50
【问题描述】:

我正在创建一个项目,我需要在单个 SQL 连接中运行 2-3 个 SQL 命令。 这是我写的代码:

SqlConnection con = new SqlConnection(@"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\project.mdf;Integrated Security=True");
con.Open();
SqlCommand cmd = new SqlCommand("select *  from " + mytags.Text + " ", con);
SqlDataReader rd = cmd.ExecuteReader();
if (rd.Read())
{
    con.Close();
    con.Open();
    SqlCommand cmd1 = new SqlCommand("insert into " + mytags.Text + " values ('fname.lname@gmail.com','" + TextBox3.Text + "','" + TextBox4.Text + "','" + TextBox5.Text + "','"+mytags.Text+"')", con);
    cmd1.ExecuteNonQuery();
    label.Visible = true;
    label.Text = "Date read and inserted";
}
else
{
    con.Close();
    con.Open();
    SqlCommand cmd2 = new SqlCommand("create table " + mytags.Text + " ( session VARCHAR(MAX) , Price int , Description VARCHAR(MAX), Date VARCHAR(20),tag VARCHAR(10))", con);
    cmd2.ExecuteNonQuery();
    con.Close();
    con.Open();
    SqlCommand cmd3 = new SqlCommand("insert into " + mytags.Text + " values ('" + Session + "','" + TextBox3.Text + "','" + TextBox4.Text + "','" + TextBox5.Text + "','" + mytags.Text + "')", con);
    cmd3.ExecuteNonQuery();
    label.Visible = true;
    label.Text = "tabel created";
    con.Close();
}

我已尝试消除错误,但我发现连接不会进入其他状态。请检查代码并建议是否有任何错误或任何其他解决方案。

【问题讨论】:

  • 如果您已经有一个同名的表但其中没有数据会怎样?您是否还考虑过如果有人在您插入的文本框中输入 SQL 会发生什么?
  • Greg 提出了一个重要问题,这是一个答案:How and why to use parameterized queries
  • 它不会到达 else 分支,因为如果表不存在,查询将出错并出现异常,而不是不返回任何行。您还应该在同一连接上执行另一个命令之前处置阅读器(尽管您的关闭和重新打开可能会间接清理它?虽然这是一种不好的形式)。有很多更好的方法可以检测表是否存在,但要以这种方式进行,您也许可以使用 try/catch。使用 ExecuteScalar() 而不是 ExecuteReader() 也可能更容易,因为无论如何您都不使用任何实际结果。

标签: c# sql-server ado.net sqlconnection sqlcommand


【解决方案1】:

只需更改SqlCommand.CommandText,而不是每次都创建一个新的SqlCommand。无需关闭并重新打开连接。

// Create the first command and execute
var command = new SqlCommand("<SQL Command>", myConnection);
var reader = command.ExecuteReader();

// Change the SQL Command and execute
command.CommandText = "<New SQL Command>";
command.ExecuteNonQuery();

【讨论】:

  • var cmd = new SqlCommand("select * from " + mytags.Text + " ", con); var rd = cmd.ExecuteReader(); if (rd.Read()) { cmd.CommandText="insert into " + mytags.Text + " values ('chirag.garg@gmail.com','" + TextBox3.Text + "','" + TextBox4.文本 + "','" + TextBox5.Text + "','"+mytags.Text+"')"; cmd.ExecuteNonQuery();
【解决方案2】:

以下应该有效。始终保持单个连接打开,只需创建新命令并执行它们。

using (SqlConnection connection = new SqlConnection(connectionString))
{
    connection.Open();
    using (SqlCommand command1 = new SqlCommand(commandText1, connection))
    {
    }
    using (SqlCommand command2 = new SqlCommand(commandText2, connection))
    {
    }
    // etc
}

【讨论】:

  • 我的第一个命令是创建一个临时表。我的下一个命令需要使用该临时表。在您的示例中,临时表消失了。当我进行跟踪时,跟踪显示我“exec CreateTableSproc”。我如何让下一个命令看到临时表?
  • @l--''''''---------'''''''''''':用TransactionScope包裹整个块。很抱歉最近的回复:))
【解决方案3】:

顺便说一句,这很可能是通过SQL注入攻击的。阅读并相应地调整您的查询是值得的。

甚至可以考虑为此创建一个存储过程并使用sp_executesql 之类的东西,当需要动态sql(即未知表名等)时,它可以提供一些保护。欲了解更多信息,请查看this link。

【讨论】:

  • 我相信参数化查询被用来缓解这个问题。
  • 任何阅读此内容的人,请忽略回复,只需搜索“参数化查询”即可。这篇文章只是令人困惑。
  • @filipe,create table 语句实际上不适用于参数化查询。在像原始海报那样构建动态 sql 时,谨慎使用 sp_executesql 之类的东西来防止误用或滥用。如果您是具有活动连接的用户的 DDL 和 DML 盟友,则尤其如此。
【解决方案4】:

我没有测试过,但主要思想是:在每个查询上加上分号。

SqlConnection connection = new SqlConnection();
SqlCommand command = new SqlCommand();
connection.ConnectionString = connectionString; // put your connection string
command.CommandText = @"
     update table
     set somecol = somevalue;
     insert into someTable values(1,'test');";
command.CommandType = CommandType.Text;
command.Connection = connection;

try
{
    connection.Open();
}
finally
{
    command.Dispose();
    connection.Dispose();
}

更新: 你可以关注 Is it possible to have multiple SQL instructions in a ADO.NET Command.CommandText property?也是

【讨论】:

    【解决方案5】:

    只需在您的连接字符串中启用此属性:

    sqb.MultipleActiveResultSets = true;

    此属性允许多个数据读取器打开一个连接。

    【讨论】:

    • 我相信这应该是答案。
    • 如果您计划启用 MARS,请务必阅读此处的“特殊注意事项”:msdn.microsoft.com/en-us/library/h32h3abf(v=vs.110).aspx
    • 我找到了答案。并在上面回答了
    • 这是正确的,除了连接字符串中的条目应该是:MultipleActiveResultSets = true;
    【解决方案6】:

    您可以在这里找到 Postgre 示例,此代码在单个 SQL 连接中运行多个 sql 命令(更新 2 列)

    public static class SQLTest
        {
            public static void NpgsqlCommand()
            {
                using (NpgsqlConnection connection = new NpgsqlConnection("Server = ; Port = ; User Id = ; " + "Password = ; Database = ;"))
                {
                    NpgsqlCommand command1 = new NpgsqlCommand("update xy set xw = 'a' WHERE aa='bb'", connection);
                    NpgsqlCommand command2 = new NpgsqlCommand("update xy set xw = 'b' where bb = 'cc'", connection);
                    command1.Connection.Open();
                    command1.ExecuteNonQuery();
                    command2.ExecuteNonQuery();
                    command2.Connection.Close();
                }
            }
        }
    

    【讨论】:

      【解决方案7】:

      如果有人有兴趣,请提供多个非查询示例。

      using (OdbcConnection DbConnection = new OdbcConnection("ConnectionString"))
      {
        DbConnection.Open();
        using (OdbcCommand DbCommand = DbConnection.CreateCommand())
        {
          DbCommand.CommandText = "INSERT...";
          DbCommand.Parameters.Add("@Name", OdbcType.Text, 20).Value = "name";
          DbCommand.ExecuteNonQuery();
      
          DbCommand.Parameters.Clear();
          DbCommand.Parameters.Add("@Name", OdbcType.Text, 20).Value = "name2";
          DbCommand.ExecuteNonQuery();
        }
      }
      

      【讨论】:

      • 谢谢,我需要这个。
      【解决方案8】:

      没有人提到这一点,但您也可以使用 ; 分隔您的命令同一命令文本中的分号:

      using (SqlConnection conn = new SqlConnection(connString))
          {
              using (SqlCommand comm = new SqlCommand())
              {
                      comm.Connection = conn;
                      comm.CommandText = @"update table ... where myparam=@myparam1 ; " +
                                          "update table ... where myparam=@myparam2 ";
                      comm.Parameters.AddWithValue("@myparam1", myparam1);
                      comm.Parameters.AddWithValue("@myparam2", myparam2);
                      conn.Open();
                      comm.ExecuteNonQuery();
      
              }
          }
      

      【讨论】:

      • 这还有一个额外的好处,那就是只有一次往返数据库,因为只有一个命令被执行。但是,请注意,SqlCommand 的参数数量限制为 2100。
      【解决方案9】:
      using (var connection = new SqlConnection("Enter Your Connection String"))
          {
              connection.Open();
          
              using (var command = connection.CreateCommand())
              {
                  command.CommandText = "Enter the First Command Here";
                  command.ExecuteNonQuery();
          
                  command.CommandText = "Enter Second Comand Here";
                  command.ExecuteNonQuery();
      
          //Similarly You can Add Multiple
              }
          }
      

      它对我有用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-11-21
        • 1970-01-01
        • 2019-12-03
        • 2021-10-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-12
        相关资源
        最近更新 更多