【问题标题】:update sql statement with unknown name/amount of params使用未知名称/参数数量更新 sql 语句
【发布时间】:2012-03-27 13:27:39
【问题描述】:

我有一个经典的 ASP 站点,我正在慢慢升级。我想创建一个函数来安全地在不手动指定参数的情况下更新 SQL 数据库。只是更有活力一点。

(我不想使用实体框架或 Linq)

这是目前为止的代码:

string updateSql = "UPDATE sometable" + "SET test1= @testData1 " + "WHERE a = @aData1";
SqlCommand UpdateCmd = new SqlCommand(updateSql, conn);
UpdateCmd.Parameters.Add("@testData1 ", SqlDbType.NVarChar, 10, "testData1 ");
UpdateCmd.Parameters.Add("@aData1", SqlDbType.NVarChar, 20, "aData1");
UpdateCmd.Parameters["@testData1 "].Value = "21515";
UpdateCmd.Parameters["@aData1"].Value = "32t3t";
UpdateCmd.ExecuteNonQuery();

伪代码(我想要实现的)

创建一个包含所有变量的 Ilist {get; set:} [在此处验证类型/长度]

为每个包含值的变量(没有验证问题)创建 sql 更新字符串。

执行它。

可能的问题: 我能预见的唯一问题是列表可能有 500 个变量,但每次 SQL 更新可能只有 2 或 3 列被更新。这效率不高吗?

【问题讨论】:

  • 你想写什么?我的意思是您可以添加一些伪代码来描述您的最佳解决方案。
  • 我不明白你在做什么。您不想手动指定参数吗?那么价值从何而来?请发布一些您正在寻找的伪代码。
  • 刚刚发布了一些姿势代码。抱歉信息不足。
  • 请不要在标题前加上“c#”等。这就是标签的用途。

标签: c# asp.net .net sql


【解决方案1】:

你需要做这样的事情......显然需要更多的编码......

 static void Main(string[] args)
    {
        var values = new Dictionary<string, object>( );

        values.Add( "name", "timmerz" );
        values.Add( "dob", DateTime.Now );
        values.Add( "sex", "m" );

        SqlUpdate( "sometable", values );
    }

    public static void SqlUpdate( string table, Dictionary<string,object> values, string where )
    {
        var equals      = new List<string>( );
        var parameters  = new List<SqlParameter>( );

        var i = 0;

        foreach( var item in values )
        {
            var pn = "@sp" + i.ToString( );

            equals.Add( string.Format( "{0}={1}", item.Key, pn ) );

            parameters.Add( new SqlParameter( pn, item.Value ) );

            i++;
        }

        string command = string.Format( "update {0} set {1} where {2}", table, string.Join( ", ", equals.ToArray( ) ), where );

        var sqlcommand = new SqlCommand(command);

        sqlcommand.Parameters.AddRange(parameters.ToArray( ) );

        sqlcommand.ExecuteNonQuery( );
    }

【讨论】:

    【解决方案2】:

    我不确定我是否完全理解您要执行的操作,但这可能与您要查找的内容接近。您可以创建任意长的参数和相应值列表,然后从该列表中动态构建相应的UPDATE

    //set up SqlCommand
    SqlCommand UpdateCmd = new SqlCommand();
    UpdateCmd.Connection = conn;
    
    //build your dictionary (probably happens elsewhere in your code)
    Dictionary<string, object> parameters = new Dictionary<string, object>();
    parameters.Add("col1", "col1 value");
    parameters.Add("col2", 42);
    parameters.Add("col3", DateTime.Now);
    
    //build a command string and add parameter values to your SqlCommand
    StringBuilder builder = new StringBuilder("UPDATE sometable SET ");
    foreach(KeyValuePair<string, object> parameter in parameters) {
        builder.Append(parameter.Key).Append(" = @").Append(parameter.Key).Append(",");
        UpdateCmd.Parameters.AddWithValue("@" + parameter.Key, parameter.Value);
    }
    builder.Remove(builder.Length - 1,1);
    
    //set the command text and execute the command
    UpdateCmd.CommandText = builder.ToString();
    UpdateCmd.ExecuteNonQuery();
    

    【讨论】:

      【解决方案3】:

      如果您使用的是 SQL Server 2008,您可以选择将参数及其值作为表传递给存储过程。 在存储过程中,您可以使用传入的表连接要更新的表。这可能比创建数百个 sep update 语句更有效。 这是一个可能有帮助的链接http://msdn.microsoft.com/en-us/library/bb675163.aspx 这是一些基于您在问题中发布的代码的示例代码

      首先创建一个要玩的表并用一些数据填充它

      CREATE TABLE [dbo].[sometable](
          [Test1] [nvarchar](100) NULL,
          [a] [nvarchar](100) NULL
      ) ON [PRIMARY]
      
      Insert sometable Select 'rerere', '122342'
      Insert sometable Select 'sfsfw', '343'
      Insert sometable Select 'sfdrgss', '434545'
      Insert sometable Select 'srgegrgeg', '3939932'
      

      然后在 SQL Server 中创建类型

      Create TYPE dbo.ParamsType AS TABLE
      ( Test1 nvarchar(100), a nvarchar(100) )
      

      然后创建接受类型作为参数的存储过程

          CREATE PROCEDURE usp_UpdateSomeTable 
      @Parameters dbo.ParamsType READONLY
      AS
      BEGIN
          SET NOCOUNT ON;
      UPDATE sometable
          SET sometable.Test1 = p.Test1
          FROM sometable INNER JOIN @Parameters as p
          ON sometable.a = p.a;
      END
      GO
      

      要从 SQL Server Management Studio 进行测试,您可以运行

      Declare @t as ParamsType
      Insert @t Select 'newValue1', '122342'
      Insert @t Select 'morenew ', '343'
      Insert @t Select 'again', '434545'
      Insert @t Select 'OnceMore', '3939932'
      
      exec usp_UpdateSomeTable @Parameters=@t
      

      从 C# 尝试测试

              static void Main(string[] args)
              {
                  System.Data.DataTable YourData = new DataTable("Parameters");
                  DataColumn column;
                  DataRow row;
      
                  column = new DataColumn();
                  column.DataType = System.Type.GetType("System.String");
                  column.ColumnName = "Test1";
                  YourData.Columns.Add(column);
      
                  column = new DataColumn();
                  column.DataType = System.Type.GetType("System.String");
                  column.ColumnName = "a";
      
                  YourData.Columns.Add(column);
      
                  row = YourData.NewRow();
                  row["Test1"] = "newValue1";
                  row["a"] = "122342";
                  YourData.Rows.Add(row);
      
                  row = YourData.NewRow();
                  row["Test1"] = "morenew";
                  row["a"] = "343";
                  YourData.Rows.Add(row);
      
                  row = YourData.NewRow();
                  row["Test1"] = "again";
                  row["a"] = "434545";
                  YourData.Rows.Add(row);
      
                  SqlConnectionStringBuilder connString = new SqlConnectionStringBuilder();
                  connString.DataSource = "127.0.0.1";
                  connString.InitialCatalog = "SO";
                  connString.IntegratedSecurity = true;
      
                  using (SqlConnection conn = new SqlConnection())
                  using (SqlCommand cmd = new SqlCommand())
                  {
                      cmd.CommandText = "usp_UpdateSomeTable";
                      cmd.CommandType = System.Data.CommandType.StoredProcedure;
                      SqlParameter p = cmd.Parameters.AddWithValue("@Parameters", YourData);
                      p.SqlDbType = SqlDbType.Structured;
                      p.TypeName = "dbo.ParamsType";
      
                      cmd.Connection = conn;
      
                      conn.ConnectionString = connString.ConnectionString;
                      conn.Open();
                      cmd.ExecuteNonQuery();
                  }
              }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-10-15
        • 1970-01-01
        • 1970-01-01
        • 2011-01-28
        • 1970-01-01
        • 2013-01-26
        • 2020-09-01
        • 1970-01-01
        相关资源
        最近更新 更多