С#, как вызвать «sp_executesql» с настраиваемыми параметрами и телом sql

Я пытаюсь выполнить динамический SQL из C# и хочу использовать sp_executesql, потому что хочу передать список строк, которые будут использоваться для оператора IN в динамическом SQL, переданном sp_executesql.

Дело в том, что я точно не знаю, как это сделать.

Пока я делал это так:

using (var dbCommand = databaseConnection.CreateCommand())
{
    dbCommand.CommandType = CommandType.StoredProcedure;
    dbCommand.CommandText = "sp_executesql";

    var sqlParam = dbCommand.CreateParameter();
    sqlParam.DbType = DbType.String;
    sqlParam.ParameterName = "stmt";
    sqlParam.Value = sql.SQL;
    dbCommand.Parameters.Add(sqlParam);

    var incidentIdParam = dbCommand.CreateParameter();
    incidentIdParam.ParameterName = "incidentId";
    incidentIdParam.DbType = DbType.Int32;
    incidentIdParam.Value = arguments.filterAttributes.incidentId;
    dbCommand.Parameters.Add(incidentIdParam);

    dbCommand.ExecuteReader();
}

Возможно ли такое?


person Alecu    schedule 07.11.2018    source источник
comment
Нет особого смысла когда-либо выполнять sp_executesql из клиентского кода, потому что клиентский код уже может параметризовать любой оператор и при необходимости выполнять текстовую замену. Вы получите (почти) тот же эффект, установив CommandText в sql.SQL и CommandType в Text. Обратите внимание, что вы не можете параметризовать предложение IN даже с sp_executesql — вы можете заменить его только текстом или использовать параметр с табличным значением. См. здесь, но обязательно прочитайте принятый ответ (который является грязным взломом).   -  person Jeroen Mostert    schedule 07.11.2018
comment
Я понял, как это сделать, вам нужно сгенерировать параметр для каждого элемента в предложении IN: stackoverflow.com/questions/9384446/   -  person Alecu    schedule 07.11.2018


Ответы (1)


Как вариант, вы можете отформатировать свой SQL на стороне клиента и передать строку готовности хранимой процедуры. Например:

sql.SQL = "UPDATE ORDERS SET STATUS = 1 WHERE ID = %param%";

тогда

sqlParam.Value = sql.SQL.Replace("%param%", arguments.filterAttributes.incidentId.ToString());
person Miamy    schedule 07.11.2018
comment
Почему бы просто не использовать параметры? Ваш метод уязвим для атаки SQL-инъекции. По возможности избегайте коротких путей. - person Mark Kram; 07.11.2018