2016-06-27 1 views
0

У меня есть следующая модификация моей хранимой процедуры:Использование EXEC для создания хранимой процедуры для запуска обновления строки столбца в SQL Server 2008

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

ALTER PROCEDURE [dbo].[spTMSA_Test_Run] 
    @TableName nvarchar(200) = 'MyTable', 
    @Parent int = 1145, 
    @Name nvarchar(100) = '''Test''', 
    @KPI nvarchar(max) = '''Test''', 
    @IDCount int = 1137 
AS 
BEGIN 
    EXEC('UPDATE ' + @TableName + ' SET Parent = ' + @Parent + ', Name = ' + @Name + ' , KPI = ' + @KPI + ' WHERE IDCount = ' + @IDCount) 
END 

Эта процедура выполняется успешно, если я дал «»»до и после строковое значение. В случае, если я оставил «до и после строкового значения, это вызовет ошибку.

Пожалуйста, помогите мне найти причину и решение. Thanks

+0

Поскольку ваш запрос является динамическим, и вы объединяете в него строку. Sql определит, что это строка, когда вы ее вложите в '' ' – Mani

ответ

1

Эта процедура является открытой дверью для атак SQL injection. Если у вас нет действительно веской причины, по которой вам нужно создать динамический SQL, я бы предложил избежать этого.

Если вы не можете избежать использования динамического sql, то вы можете использовать только quotename, чтобы ваша процедура была более безопасной.

Что касается проблемы вы заявляете в вашем вопросе - просто переместить ''' в тело запроса:

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

ALTER PROCEDURE [dbo].[spTMSA_Test_Run] 
    @TableName nvarchar(200) = 'MyTable', 
    @Parent int = 1145, 
    @Name nvarchar(100) = 'Test', 
    @KPI nvarchar(max) = 'Test', 
    @IDCount int = 1137 
AS 
BEGIN 

    EXEC('UPDATE QUOTENAME(' + @TableName + ') 
      SET Parent = ' + @Parent + ', 
       Name = ''' + @Name + ''' , 
       KPI = ''' + @KPI + ''' 
      WHERE IDCount = ' + @IDCount) 
END 
+0

Спасибо, Зоар, – user3717655

0
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

ALTER PROCEDURE [dbo].[spTMSA_Test_Run] 
    @TableName nvarchar(200) = 'MyTable', 
    @Parent int = 1145, 
    @Name nvarchar(100) = '''Test''', 
    @KPI nvarchar(max) = '''Test''', 
    @IDCount int = 1137 
AS 
BEGIN 

  declare @sql nvarchar(4000) 
  set @sql='UPDATE ' + @TableName + ' SET Parent = ' + @Parent + ', Name = ' + @Name + ' , KPI = ' + @KPI + ' WHERE IDCount = ' + @IDCount 
  print @sql --find reason in the sql statement 
    EXEC(@sql) 
END 
0

Я предлагаю использовать sp_executesql и CAST int для nvarchar перед выполнением запроса и QUOTENAME в @tablename ,

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

ALTER PROCEDURE [dbo].[spTMSA_Test_Run] 
    @TableName nvarchar(200), 
    @Parent int, 
    @Name nvarchar(100), 
    @KPI nvarchar(max), 
    @IDCount int 
AS 
BEGIN 

    DECLARE @sql nvarchar(max) 

    SELECT @sql = ' 
     UPDATE ' + QUOTENAME(@TableName) + ' 
     SET Parent = ' + CAST(@Parent as nvarchar(10))+ ', 
      Name = ''' + @Name + ''', 
      KPI = ''' + @KPI + ''' 
     WHERE IDCount = ' + CAST(@IDCount as nvarchar(10)) + ';' 


    EXEC sp_executesql @sql 

END 
Смежные вопросы