Как в SQL ссылаться на параметр / переменную при использовании ЗАПРЕТИТЬ ОБНОВЛЕНИЕ?

#sql #sql-server #variables #parameters

#sql #sql-server #переменные #параметры

Вопрос:

 CREATE PROCEDURE cspFieldAccess
@Tbl varchar(20),
@Fld varchar(20),
@Usr varchar(35),
@Dny varchar(5),
@All varchar(5)
AS
IF @Dny = 'Y' and @All = 'Y' 
DENY UPDATE ON [@Tbl] ([@Fld]) TO [MCCOSKERSViewPoint Production Users] ;
ELSE IF @Dny = 'Y' and @All = 'N'
DENY UPDATE ON [@Tbl] ([@Fld]) TO [@Usr] ;
ELSE IF @Dny = 'N' and @All = 'Y' 
GRANT UPDATE ON [@Tbl] ([@Fld]) TO [MCCOSKERSViewPoint Production Users] ;
ELSE IF @Dny = 'N' and @All = 'N'
DENY UPDATE ON [@Tbl] ([@Fld]) TO [@Usr] ;

EXEC cspFieldAccess 'HQRV', RevEmail, 'MCCOSKERSPGunston', Y, N
  

Приведенный выше код выдает сообщение об ошибке:

 Cannot find the object '@Tbl', because it does not exist or you do not have permission.
  

Вместо запроса, ищущего таблицу с именем «@Tbl», я хочу, чтобы он указывал значение, присвоенное параметру @Tbl .

Как я могу этого добиться?

Приведенный ниже запрос

Ответ №1:

Используйте динамический SQL:

         declare
        @Tbl varchar(20),
        @Fld varchar(20),
        @sql nvarchar(max)

        set @Tbl = 'table'
        set @Fld = 'field'
        set @sql='DENY UPDATE ON [' @Tbl '] ([' @Fld] ') TO [MCCOSKERSViewPoint Production Users]'
        print @sql
        --exec sp_executesql @sql
  

После запуска и печати убедитесь, что все выглядит нормально, затем раскомментируйте EXEC и попробуйте.

Будьте осторожны с SQL-инъекциями, если пользователи могут изменять переменные, вы рискуете.

Ответ №2:

SQL Server интерпретируется так, что выражение вычисляется так, как вы его ввели. Для замены переменных в вам необходимо использовать динамический SQL. Однако будьте осторожны, поскольку оператор exec открывает вам доступ к sql-инъекции.

 declare @Tbl varchar(20) = 'foo'
declare @Fld varchar(20) = 'bar'
declare @login  varchar(100) = '[MCCOSKERSViewPoint Production Users]'
declare @sql varchar(max)
set @sql = 'DENY UPDATE ON ['   @Tbl   '] (['   @Fld   ']) TO '   @login    ' ;'
exec(@sql)
  

Вы также можете использовать режим Query-> SQLCMD и попробовать следующее, в котором используется синтаксис SQLCMD для замены в переменных, если это вам нравится.

 :setvar Tbl  foo
:setvar Fld  bar
DENY UPDATE ON [$(Tbl)] ([$(Fld)]) TO [MCCOSKERSViewPoint Production Users];