В MS SQL Server я всегда ненавидел больше всего на свете то, как работает система безопасности. Контекст безопасности постоянно меняется, если вы смотрите на сервер смешно, и зачастую очень трудно (во всяком случае, для меня) прогнозировать или отлаживать.
Имея дело с сегодняшней проблемой, я подумал: «Хотел бы я просто добавить в свой код строку, которая отображала бы контекст безопасности, используемый SQL Server при запуске этого кода». Существует ли такая команда? Например, SELECT security_context()
Чтобы быть немного понятнее ... если я нахожусь в хранимой процедуре и поэтому для нее требуется контекст безопасности владельца SP, то я бы хотел это увидеть. Если я нахожусь в коде, который был вызван sp_executesql, и это приводит к тому, что безопасность находится в контексте учетной записи службы SQL Server, то я хотел бы увидеть это.
По крайней мере, тогда я смогу понять, почему SQL Server считает, что у меня не должно быть доступа к чему-либо.
Спасибо!
Пример
-- Set up
CREATE USER Test_User WITHOUT LOGIN
CREATE TABLE Test_Security_Context (my_id INT)
INSERT INTO Test_Security_Context VALUES (1)
DENY SELECT ON Test_Security_Context TO Test_User
GO
CREATE PROCEDURE Test_Security_Context_SP
AS
SELECT SUSER_SNAME()
SELECT * FROM Test_Security_Context -- This will return ok
EXEC('SELECT SUSER_SNAME(); SELECT * FROM Test_Security_Context') -- SUSER_SNAME() will match above but select fails
GO
GRANT EXECUTE ON Test_Security_Context_SP TO Test_User
GO
-- Switch to the new user
SETUSER 'Test_User'
GO
-- Do the test
EXEC Test_Security_Context_SP
GO
-- Clean up
SETUSER
DROP PROCEDURE Test_Security_Context_SP
DROP TABLE Test_Security_Context
DROP USER Test_User
GO