2015-09-28 3 views
0

Мне нужно удалить (прочитать/обновить) некоторые значения в некоторых таблицах и хотеть использовать хранимую процедуру для уменьшения проблем безопасности.Хранимая процедура SQL Server: динамически удалять запись

Поскольку таблиц много, а записи еще больше, и нет смысла писать хранимую процедуру для каждой комбинации, и, поскольку у всех есть такая потребность, я думал, что было бы легко найти хранимую процедуру для этого. но много гуглинга я не нашел простого и короткого ответа, поэтому я попытался создать свою собственную хранимую процедуру. Но я боюсь, что это может иметь некоторые проблемы с безопасностью: в основном, когда я объявляю @Table как nvarchar(30) .. Я попытался объявить как ТАБЛИЦУ, но он возвращает ошибку.

Может подсказать, что не приемлемо и предложить решение?

Благодаря

Здесь хранимая процедура для удаления .. но для других действий может быть аналогичен:

CREATE PROCEDURE dbo.spDeleteRecord 
(
    @UID  nvarchar(20) = NOT NULL, 
    @PWD  nvarchar(30) = NOT NULL, 
    @Table  sysname, 
    @WhereField sysname, 
    @WhereValue nvarchar(150) = NOT NULL 
) 
AS 
    SET NOCOUNT ON; 

    DECLARE @S nvarchar(max) = '', 
      @P nvarchar(max) = '' 

    SET @S = 'DELETE t 
       from dbo.'+quotename(@Table)+' t 
       join dbo.subUsers su on t.UID = su.UID 
       where ' + quotename(@WhereField) + ' = @_WhereValue 
       and su.SUID = @_UID 
       and su.PWD = @_PWD'  

    SET @P = '@_UID nvarchar(50), 
      @_PWD nvarchar(50), 
      @_Table sysname, 
      @_WhereField sysname, 
      @_WhereValue nvarchar(150)' 

    --PRINT @S 
    EXEC sp_executesql @S, @P, @UID, @PWD, @Table, @WhereField, @WhereValue 

    SET NOCOUNT OFF 

Спасибо за чтение Джо

+1

динамический proc для удаления строк ... что может пойти не так! –

+0

Зачем этот код? Почему бы не использовать 'CASCADE DELETE' в внешних ключах или TRIGGER, который удаляет связанные записи? Это не только проблемы * безопасности *. Если вы не вызываете * все *, удаляет внутри одной процедуры, у вас будут записи зомби. Почему бы не написать * одну хранимую процедуру для удаления всех связанных записей? Вы даже можете использовать генерацию кода для создания операторов удаления –

+0

, но это простые таблицы без связанных записей. В основном это таблица, содержащая имя пользователя, активировавшего определенную услугу , и пользователь может изменить свою собственную подписку. в любом случае .. никогда не использовал 'CASCADE DELETE', но он может быть полезен в другой ситуации. Спасибо за совет. – Joe

ответ

1

Вы должны были бы сделать это следующим образом:

SET @S = 'DELETE t 
      from dbo.'+quotename(@Table)+' t 
      join dbo.subUsers su on t.UID = su.UID 
      where ' + quotename(@WhereField) + ' = @_WhereValue 
      and su.SUID = @_UID 
      and su.PWD = @_PWD'  

SET @P = '@_UID nvarchar(50), 
     @_PWD nvarchar(50), 
     @_WhereValue nvarchar(150)' 

--PRINT @S 
EXEC sp_executesql @S, @P, @_WhereValue = @WhereValue, @_UID = @UID, @_PWD = @PWD 

В принципе, список параметров ca n относятся только к параметрам, которые фактически встроены в строку SQL.

Также обратите внимание, что @Table и @WhereField верны как тип данных sysname. Я также, вероятно, ограничил бы @UID, @PWD и @WhereValue до NOT NULL, потому что я ненавижу необработанные нули.

Однако вам действительно нужно рассмотреть, хотите ли вы это сделать. Для меня это похоже на то, чтобы оставить заряженный пистолет. Что происходит, когда вы вызываете это с таблицей, которая имеет поле UID, которое совпадает с значениями в таблице dbo.subUsers, даже если там не существует никакого отношения? Я не вижу существенного преимущества этого метода, поскольку просто запускает параметризованный запрос из вашего приложения, а тот факт, что запрос изменяется между казнями, означает, что вы можете столкнуться с проблемами с sniffing параметров, чтобы в итоге вы могли выполнить субоптимальные планы выполнения.

+0

Спасибо, что ответили .. ну да .. 'NOT NULL' в полях ввода, тогда .. какая разница, чтобы написать' @_WhereValue = @WhereValue, @_UID = @UID, @_PWD = @ PWD' в EXEC вместо просто , @WhereValue, @UID, @PWD? Поскольку таблица, которую предполагается изменить с помощью этого sproc, составляет только 12, может помочь смягчить риск, проверяя, включен ли '@ Table' в список? Мой страх - просто оставить ребенку заряженный пистолет.но другое решение может состоять в том, чтобы написать 12 sproc с уже установленным «TableName». Или я что-то не рассматриваю? спасибо – Joe

+0

@Joe Ну, это не просто то, что я изменил его на '@_WhereValue = @WhereValue, @_UID = @UID, @_PWD = @ PWD', это то, что я исключил' @ Table' и '@ WhereField' из список параметров. Фиксированный набор известных таблиц, безусловно, помогает с рискованной частью, но в конце концов вы все еще вернулись к точке «Что это добавляет? Почему это проще, когда вы отказываетесь от гибкости написания запроса? а не функция в приложении, где вы можете указать перечисления и проверить запрос? » Я не говорю, что это неправильно делать так, как вы, но некоторые могут. Это странно. –

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