Consider this design method.
USE "master";
-- Create our test logins (don't forget to tidy these up later!)
CREATE LOGIN "batman"
WITH PASSWORD = N''
, CHECK_EXPIRATION = OFF
, CHECK_POLICY = OFF;
CREATE LOGIN "robin"
WITH PASSWORD = N''
, CHECK_EXPIRATION = OFF
, CHECK_POLICY = OFF;
USE "playdb";
-- Create the corresponding users
CREATE USER "batman"
FOR LOGIN "batman";
CREATE USER "robin"
FOR LOGIN "robin";
-- Grant them some select permissions
EXEC sp_addrolemember N'db_datareader', N'batman';
EXEC sp_addrolemember N'db_datareader', N'robin';
-- Create our "user access" table
DECLARE @users table (
username sysname NOT NULL
, access_from date NOT NULL DEFAULT '1900-01-01' -- Deliberately not allowing nulls and setting the widest possible value range
, access_to date NOT NULL DEFAULT '9999-12-31' -- this will make our queries so much easier!
);
-- Give one user full permissions
INSERT INTO @users (username)
VALUES ('batman');
-- Limit what this chappy can see
INSERT INTO @users (username, access_from, access_to)
VALUES ('robin', '2011-01-01', '2012-01-01');
-- Example data table
DECLARE @data table (
date_field date NOT NULL
);
-- ...with example data
INSERT INTO @data (date_field)
VALUES ('2010-01-01')
, ('2011-01-01')
, ('2012-01-01')
, ('2012-01-01')
, ('2013-01-01')
, ('2014-01-01');
-- Let's mimic our full access user
SETUSER 'batman';
SELECT System_User As current_username
, *
FROM @data As data
WHERE EXISTS ( -- Limit the records to only those this user is allowed to see
SELECT *
FROM @users
WHERE username = System_User
AND data.date_field >= access_from
AND data.date_field < access_to
);
SETUSER; -- Reset user
-- Imitate the chap with restricted access
SETUSER 'robin';
-- Exacty same query as before
SELECT System_User As current_username
, *
FROM @data As data
WHERE EXISTS (
SELECT *
FROM @users
WHERE username = System_User
AND data.date_field >= access_from
AND data.date_field < access_to
);