Friday, April 4, 2014

Row Level Security in MS SQL

Dear Josh,

You just got back from the excellent Kimball DW/BI Lifecycle in Depth in NYC, and one of the concepts briefly mentioned was row level security.  You made a note to look into this and came up with this demo script:


/* Companies table -- I should only be able to see the customers in my company. */
  
DECLARE @Companies TABLE (
      
CompanyId INT IDENTITY NOT NULL,
      
CompanyName VARCHAR(50) NOT NULL
   );

  
INSERT INTO @Companies
      
(CompanyName)
  
VALUES
      
('My Company'),
       (
'Not My Company')
/* Customers table */
  
DECLARE @Customers TABLE (
      
CustomerId INT IDENTITY NOT NULL,
      
CustomerFirstName VARCHAR(50) NOT NULL,
      
CustomerLastName VARCHAR(50) NOT NULL,
      
CustomerDateOfBirth DATETIME NOT NULL,
      
CompanyId INT NULL
   );

  
INSERT INTO @Customers
      
(CustomerFirstName, CustomerLastName, CustomerDateOfBirth, CompanyId)
  
VALUES
      
('John', 'Smith', '8-1-1988', 1),
       (
'Abe', 'Jones', '6-15-1951', 2),
       (
'Mike', 'Bullard', '11-8-1960', 1),
       (
'Joan', 'Smith', '1-11-1987', 2),
       (
'Albert', 'Simpson', '3-3-1980', 1),
       (
'Frank', 'Taylor', '9-12-1962', 2),
       (
'Mo', 'Robinson', '8-12-1953', 1),
       (
'Tina', 'Sommer', '2-14-1978', 2)
/* SalesPeople table */
  
DECLARE @SalesPeople TABLE (
      
SalesPersonId INT IDENTITY NOT NULL,
      
SalesPerson VARCHAR(50) NOT NULL,
      
CompanyId INT NULL
   );

  
INSERT INTO @SalesPeople
      
(SalesPerson, CompanyId)
  
VALUES
      
(SUSER_SNAME(), 1),
       (
'Not Me', 2)
/* My Company's customers */
  
SELECT
      
CU.CustomerId,
      
CU.CustomerFirstName,
      
CU.CustomerLastName,
      
CU.CustomerDateOfBirth,
      
CO.CompanyName,
      
SP.SalesPerson AS SalesPerson
  
FROM
      
@Customers CU
      
INNER JOIN
      
@Companies CO ON CU.CompanyId = CO.CompanyId
      
INNER JOIN
      
@SalesPeople SP ON CO.CompanyId = Sp.CompanyId
  
WHERE
      
SP.SalesPerson = SUSER_SNAME()
/* Not My Company's customers */
  
SELECT
      
CU.CustomerId,
      
CU.CustomerFirstName,
      
CU.CustomerLastName,
      
CU.CustomerDateOfBirth,
      
CO.CompanyName,
      
SP.SalesPerson AS SalesPerson
  
FROM
      
@Customers CU
      
LEFT JOIN
      
@Companies CO ON CU.CompanyId = CO.CompanyId
      
LEFT JOIN
      
@SalesPeople SP ON CO.CompanyId = Sp.CompanyId
  
WHERE
      
SP.SalesPerson <> SUSER_SNAME() OR
      
SP.SalesPerson IS NULL

No comments:

Post a Comment

Please only include comments that add to the substance of the Blog Post:
- Question or request for clarification
- Idea for improvement
- Identifying an issue

Please refrain from promotion.