#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];