обновить SQL-оператор с неизвестным именем / количеством параметров

У меня есть классический сайт ASP, который я постепенно обновляю. Я хотел бы создать функцию длябезопасно обновить базу данных SQL без указания параметров вручную. Что-то чуть более динамичное.

(Я не хочу использовать сущность Framework или 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 обновляемых столбца. Разве это не эффективно?

 tdjfdjdj27 мар. 2012 г., 15:37
только что опубликовал какой-то посеудокод Извините за отсутствие информации.
 Adriano Repetti27 мар. 2012 г., 15:29
Что бы вы хотели написать? Я имею в виду, что вы можете добавить псевдокод, чтобы описать ваше оптимальное решение.
 John Saunders27 мар. 2012 г., 18:02
Пожалуйста, не ставьте префиксы перед вашими буквами "c #" и тому подобное. Вот для чего нужны теги.
 ean553327 мар. 2012 г., 15:35
Я не понимаю, что ты пытаешься сделать. Вы не хотите указывать параметры вручную? Тогда откуда эти ценности? Пожалуйста, опубликуйте псевдокод того, что вы ищете.

Ответы на вопрос(3)

что полностью понимаю, что вы пытаетесь сделать, но это может быть близко к тому, что вы ищете. Вы можете создать произвольно длинный список параметров и соответствующих значений, а затем создать соответствующий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();

у вас есть возможность передать параметры и их значения в виде таблицы в хранимую процедуру. Внутри хранимой процедуры вы можете объединить таблицу для обновления с переданной таблицей. Это, вероятно, будет более эффективным, чем создание сотен операторов 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 @[email protected]

Чтобы проверить из 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();
            }
        }
Решение Вопроса

нужно больше кодирования ....

 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( );
    }

Ваш ответ на вопрос