Использование такого динамического SQL - признак плохого дизайна, как в дизайне базы данных, так и в дизайне приложения.
Однако, предполагая, что дизайн не может быть изменен, проблема с вашим текущим оператором SQL заключается в том, что вы фактически не используете динамический SQL.
Динамический SQL для этого будет выглядеть следующим образом:
DECLARE @sqlSubstr nvarchar(max) = N'UPDATE '+ quotename(@tempTable) +N'
SET '+ quotename(@flag) +N' = 1
WHERE '+ quotename(@tempCol) +' = @tempColVal;
EXECUTE sp_executesql @sqlSubstr, N'@tempColVal varchar(2)', @tempColVal;
Обратите внимание, что параметры для имени таблицы и имен столбцов объединяются в строку, представляющую SQL, который вы выполняете.
Также обратите внимание, что я добавил quotename
и к именам столбцов.
Однако я не уверен, что это обеспечивает полную защиту от атак SQL-инъекций.Использование quotename
действительно обеспечивает некоторую защиту, но я уверен, что это можно преодолеть.
Чтобы по-настоящему защитить себя, вы должны внести в белый список все идентификаторы - поэтому сначала вам нужно запросить information_schema.columns
, чтобыубедитесь, что все безопасно.
Только после этого вы можете быть уверены, что код безопасен для SQL-инъекций.Пока мы на этом, , вам действительно следует прекратить использовать AddWithValue.
Вот пересмотренная версия вашего кода:
string sqlStr = @"DECLARE @sqlSubstr nvarchar(max) =
N'UPDATE '+ quotename(@tempTable) +
N' SET '+ quotename(@flag) +
N' = 1 WHERE '+ quotename(@tempCol) +' = @tempColVal'
IF EXISTS(
-- make sure both columns exists in the table
SELECT 1
FROM Information_schema.Columns
WHERE Table_Name = @tempTable
AND Column_Name IN(@flag, @tempCol)
HAVING COUNT(DISTINCT Column_Name) = 2
)
EXECUTE sp_executesql @sqlSubstr N'@tempColVal nvarchar' @tempColVal"; -- I had to guess the data type
command.CommandText = sqlStr;
command.Parameters.Add("@tempTable", SqlDbType.NVarChar).Value = TemporaryTableName;
command.Parameters.Add("@flag", SqlDbType.NVarChar).Value = flagToUpdate;
command.Parameters.Add("@tempCol", SqlDbType.NVarChar).Value = ImportRegister.TemporaryTableKeyColumn;
command.Parameters.Add("@tempColVal", SqlDbType.NVarChar).Value = sourceRow[ImportRegister.TemporaryTableKeyColumn]);
command.ExecuteNonQuery();