<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: SQL Server Row Level Security @ Richmond Code Camp 2009.1</title>
	<atom:link href="http://robertlambert.net/2009/04/sql-server-row-level-security-richmond-code-camp-20091/feed/" rel="self" type="application/rss+xml" />
	<link>http://robertlambert.net/2009/04/sql-server-row-level-security-richmond-code-camp-20091/</link>
	<description>on business-aligned information technology</description>
	<lastBuildDate>Fri, 09 Jul 2010 12:18:43 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
	<item>
		<title>By: Bob</title>
		<link>http://robertlambert.net/2009/04/sql-server-row-level-security-richmond-code-camp-20091/comment-page-1/#comment-65</link>
		<dc:creator>Bob</dc:creator>
		<pubDate>Mon, 27 Apr 2009 13:49:40 +0000</pubDate>
		<guid isPermaLink="false">http://robertlambert.net/?p=411#comment-65</guid>
		<description>Here are the object creates and presentation scripts presented  in

Pretty Good Row Level Security

At Richmond Code Camp 2009.1 (&lt;a href=&quot;http://richmondcodecamp.org/&quot; rel=&quot;nofollow&quot;&gt;http://richmondcodecamp.org/&lt;/a&gt;) 
Bob Lambert and 
Nic Morel

CapTech Ventures, Inc.
blambert@captechventures.com, http://robertlambert.net 
nmorel@captechventures.com
See also Protecting Your Data with Row Level Security for SQL Server Databases at Dr Dobbs Portal, http://www.ddj.com/database/215900773 

Note: users other than dbo are granted only access to views, that is in example 2 mdavis should only have access to the view ordersummary, in the later examples bobama only to vssalestotals and vsemployee.

---------------------------------------------------------------------------
-- Sales user Access table
USE [AdventureWorks]
GO
/****** Object:  Table [Security].[SalesAccess]    Script Date: 04/27/2009 08:11:14 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [Security].[SalesAccess](
	[UserID] [varchar](20) NOT NULL,
	[TerritoryID] [int] NOT NULL
) ON [PRIMARY]

GO

---------------------------------------------------------------------------
-- HR User Access Table

SET ANSI_PADDING ON
USE [AdventureWorks]
GO
/****** Object:  Table [Security].[HRAccess]    Script Date: 04/27/2009 08:11:56 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [Security].[HRAccess](
	[UserID] [varchar](20) NOT NULL,
	[DepartmentID] [smallint] NOT NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING ON

---------------------------------------------------------------------------
-- select * from [Security].[SalesAccess]    


UserID               TerritoryID
-------------------- -----------
sordway              1
sordway              2
sordway              3
bobama               1
jmccain              2
jkerry               6
jkerry               7
jkerry               8
jkerry               9
mromney              7
mromney              8
dbo                  1
dbo                  2

---------------------------------------------------------------------------
-- select * from [Security].[HRAccess]   

UserID               DepartmentID
-------------------- ------------
bobama               4
bobama               5
bobama               6
dbo                  5
dbo                  6
dbo                  7
dbo                  8
dbo                  9
dbo                  10
dbo                  11
dbo                  12
dbo                  13
dbo                  14
dbo                  15
dbo                  16

(15 row(s) affected)



---------------------------------------------------------------------------
-- table valued function accessing sales data joining to the sales security access table


USE [AdventureWorks]
GO
/****** Object:  UserDefinedFunction [Security].[ufnGetSalesTotals]    Script Date: 04/25/2009 12:25:48 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE FUNCTION [Security].[ufnGetSalesTotals] 
(	
	@UserId VARCHAR(20)
)
RETURNS TABLE 
AS
RETURN 
(
	SELECT 
		pvt.[SalesPersonID]
		,pvt.[FullName]
		,pvt.[Title]
		,pvt.[SalesTerritory]
		,pvt.[2002]
		,pvt.[2003]
		,pvt.[2004] 
	FROM (SELECT 
			soh.[SalesPersonID]
			,c.[FirstName] + &#039; &#039; + COALESCE(c.[MiddleName], &#039;&#039;) + &#039; &#039; + c.[LastName] AS [FullName]
			,e.[Title]
			,st.[Name] AS [SalesTerritory]
			,soh.[SubTotal]
			,YEAR(DATEADD(m, 6, soh.[OrderDate])) AS [FiscalYear] 
		FROM [Sales].[SalesPerson] sp 
			INNER JOIN [Sales].[SalesOrderHeader] soh 
			ON sp.[SalesPersonID] = soh.[SalesPersonID]
			INNER JOIN [Sales].[SalesTerritory] st 
			ON sp.[TerritoryID] = st.[TerritoryID]
			INNER JOIN Security.SalesAccess sa   /* this is the added join */
			ON sa.TerritoryID = st.[TerritoryID]
			AND sa.UserId = @UserID
			INNER JOIN [HumanResources].[Employee] e 
			ON soh.[SalesPersonID] = e.[EmployeeID] 
			INNER JOIN [Person].[Contact] c 
			ON e.[ContactID] = c.ContactID 
		) AS soh 
	PIVOT 
	(
		SUM([SubTotal]) 
		FOR [FiscalYear] 
		IN ([2002], [2003], [2004])
	) AS pvt
)

---------------------------------------------------------------------------
-- View passing userid to the function above


USE [AdventureWorks]
GO
/****** Object:  View [Security].[vsSalesTotals]    Script Date: 04/25/2009 12:26:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE VIEW [Security].[vsSalesTotals] 
AS 
SELECT 
		 [SalesPersonID]
		,[FullName]
		,[Title]
		,[SalesTerritory]
		,[2002]
		,[2003]
		,[2004] 

FROM Security.ufnGetSalesTotals(USER)

---------------------------------------------------------------------------
-- table valued function accessing employee data joining to the HR security access table


USE [AdventureWorks]
GO
/****** Object:  UserDefinedFunction [Security].[ufnGetEmployeeData]    Script Date: 04/25/2009 12:26:37 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE FUNCTION [Security].[ufnGetEmployeeData] 
(	
	@UserId VARCHAR(20)
)
RETURNS TABLE 
AS
RETURN 
(
	SELECT 
		e.[EmployeeID]
		,c.[Title]
		,c.[FirstName]
		,c.[MiddleName]
		,c.[LastName]
		,c.[Suffix]
		,e.[Title] AS [JobTitle] 
		,edh.DepartmentID
		,dpt.Name AS [DepartmentName]
		,shr.UserID
		,c.[Phone]
		,c.[EmailAddress]
		,c.[EmailPromotion]
		,a.[AddressLine1]
		,a.[AddressLine2]
		,a.[City]
		,sp.[Name] AS [StateProvinceName] 
		,a.[PostalCode]
		,cr.[Name] AS [CountryRegionName] 
		,c.[AdditionalContactInfo]
	FROM [HumanResources].[Employee] e
		INNER JOIN [Person].[Contact] c 
		ON c.[ContactID] = e.[ContactID]
		INNER JOIN [HumanResources].[EmployeeAddress] ea 
		ON e.[EmployeeID] = ea.[EmployeeID] 
		INNER JOIN [Person].[Address] a 
		ON ea.[AddressID] = a.[AddressID]
		INNER JOIN [Person].[StateProvince] sp 
		ON sp.[StateProvinceID] = a.[StateProvinceID]
		INNER JOIN [Person].[CountryRegion] cr 
		ON cr.[CountryRegionCode] = sp.[CountryRegionCode]
		INNER JOIN HumanResources.EmployeeDepartmentHistory edh
		ON edh.EmployeeID = e.EmployeeID
		AND	edh.EndDate is null
		INNER JOIN Security.HRAccess shr /* this is the added join */
		ON shr.DepartmentID = edh.DepartmentID
		and shr.UserID = @UserID
		INNER JOIN HumanResources.Department dpt
		ON dpt.DepartmentID = edh.DepartmentID
)
---------------------------------------------------------------------------
-- View passing userid to the function above

USE [AdventureWorks]
GO
/****** Object:  View [Security].[vsEmployee]    Script Date: 04/25/2009 12:27:01 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE VIEW [Security].[vsEmployee] 
AS 
SELECT 
 		[EmployeeID]
		,[Title]
		,[FirstName]
		,[MiddleName]
		,[LastName]
		,[Suffix]
		,[JobTitle] 
		,DepartmentID
		,[DepartmentName]
		,UserID
		,[Phone]
		,[EmailAddress]
		,[EmailPromotion]
		,[AddressLine1]
		,[AddressLine2]
		,[City]
		,[StateProvinceName] 
		,[PostalCode]
		,[CountryRegionName] 
		,[AdditionalContactInfo]
FROM Security.ufnGetEmployeeData(USER)
    
GO
EXEC sys.sp_addextendedproperty @name=N&#039;MS_Description&#039;, @value=N&#039;Employee names and addresses.&#039; , @level0type=N&#039;SCHEMA&#039;,@level0name=N&#039;Security&#039;, @level1type=N&#039;VIEW&#039;,@level1name=N&#039;vsEmployee&#039;

---------------------------------------------------------------------------
-- Presentation scripts

------------------------------------
-- Dr Dobbs Example 1: dbo
------------------------------------

-- Connect blambert

use rls

--The database includes these orders

select * from orders
where department in (&#039;East&#039;, &#039;Southeast&#039;, &#039;Northeast&#039;)

--Here are the contents of the user access table
select * from useraccess;

--and here are the results of a query summing orders accessible by 
-- a particular user
select * from getordersummary (&#039;blambert&#039;)

-- here&#039;s the view encapsulating the getordersummary function

select * from ordersummary

select user

------------------------------------
-- Dr Dobbs Example 2: mdavis
------------------------------------

-- Connect mdavis
select user

use rls

--review the orders table

select * from orders
where department in (&#039;East&#039;, &#039;Southeast&#039;, &#039;Northeast&#039;)

--review the user access table
select * from useraccess;

--review the getordersummary table-valued function
select * from getordersummary (&#039;mdavis&#039;)

-- review the ordersummary view

select * from ordersummary

------------------------------------
-- AdventureWorks Example 1: dbo
------------------------------------

-- Connect blambert

use AdventureWorks

--Adventureworks includes this view, providing a pivoted sales report

select * from Sales.vSalesPersonSalesByFiscalYears 

--Here are the contents of the user access table

select * from Security.SalesAccess

--Here are territory codes

select * from Sales.SalesTerritory

--and here are the results of a query summing orders accessible by 
-- a particular user
select * from Security.ufnGetSalesTotals(&#039;jmccain&#039;)

-- here&#039;s the view encapsulating the getordersummary function

select * from Security.vsSalesTotals

select user

------------------------------------
-- AdventureWorks Example 1: bobama
------------------------------------

-- Connect bobama

use AdventureWorks

--Adventureworks includes this view, providing a pivoted sales report

select * from Sales.vSalesPersonSalesByFiscalYears 

--Here are the contents of the user access table

select * from Security.SalesAccess

--Here are territory codes

select * from Sales.SalesTerritory

--and here are the results of a query summing orders accessible by 
-- a particular user
select * from Security.ufnGetSalesTotals(&#039;bobama&#039;)

-- here&#039;s the view encapsulating the getordersummary function

select * from Security.vsSalesTotals

select user

------------------------------------
-- AdventureWorks Example 2: dbo
------------------------------------

-- Connect blambert

use AdventureWorks

--Adventureworks includes this view, providing employee data

select * from HumanResources.vEmployee 

--Here are the contents of the user access table

select * from Security.HRAccess

--Here are department ids

select * from HumanResources.Department
select * from HumanResources.EmployeeDepartmentHistory where enddate is null

--and here are the results of a query summing using the table valued function to list employees

select * from Security.ufnGetEmployeeData(&#039;jmccain&#039;)

-- here&#039;s the view encapsulating the ufnGetEmployeeData function

select * from Security.vsEmployee

select user
------------------------------------
-- AdventureWorks Example 2: bobama
------------------------------------

-- Connect bobama

use AdventureWorks

--Adventureworks includes this view, providing employee data

select * from HumanResources.vEmployee 

--Here are the contents of the user access table

select * from Security.HRAccess

--Here are department ids

select * from HumanResources.Department
select * from HumanResources.EmployeeDepartmentHistory where enddate is null

--and here are the results of a query summing using the table valued function to list employees

select * from Security.ufnGetEmployeeData(&#039;jmccain&#039;)

-- here&#039;s the view encapsulating the ufnGetEmployeeData function

select * from Security.vsEmployee

select user</description>
		<content:encoded><![CDATA[<p>Here are the object creates and presentation scripts presented  in</p>
<p>Pretty Good Row Level Security</p>
<p>At Richmond Code Camp 2009.1 (<a href="http://richmondcodecamp.org/" rel="nofollow">http://richmondcodecamp.org/</a>)<br />
Bob Lambert and<br />
Nic Morel</p>
<p>CapTech Ventures, Inc.<br />
<a href="mailto:blambert@captechventures.com">blambert@captechventures.com</a>, <a href="http://robertlambert.net" rel="nofollow">http://robertlambert.net</a><br />
<a href="mailto:nmorel@captechventures.com">nmorel@captechventures.com</a><br />
See also Protecting Your Data with Row Level Security for SQL Server Databases at Dr Dobbs Portal, <a href="http://www.ddj.com/database/215900773" rel="nofollow">http://www.ddj.com/database/215900773</a> </p>
<p>Note: users other than dbo are granted only access to views, that is in example 2 mdavis should only have access to the view ordersummary, in the later examples bobama only to vssalestotals and vsemployee.</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
&#8211; Sales user Access table<br />
USE [AdventureWorks]<br />
GO<br />
/****** Object:  Table [Security].[SalesAccess]    Script Date: 04/27/2009 08:11:14 ******/<br />
SET ANSI_NULLS ON<br />
GO<br />
SET QUOTED_IDENTIFIER ON<br />
GO<br />
SET ANSI_PADDING ON<br />
GO<br />
CREATE TABLE [Security].[SalesAccess](<br />
	[UserID] [varchar](20) NOT NULL,<br />
	[TerritoryID] [int] NOT NULL<br />
) ON [PRIMARY]</p>
<p>GO</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
&#8211; HR User Access Table</p>
<p>SET ANSI_PADDING ON<br />
USE [AdventureWorks]<br />
GO<br />
/****** Object:  Table [Security].[HRAccess]    Script Date: 04/27/2009 08:11:56 ******/<br />
SET ANSI_NULLS ON<br />
GO<br />
SET QUOTED_IDENTIFIER ON<br />
GO<br />
SET ANSI_PADDING ON<br />
GO<br />
CREATE TABLE [Security].[HRAccess](<br />
	[UserID] [varchar](20) NOT NULL,<br />
	[DepartmentID] [smallint] NOT NULL<br />
) ON [PRIMARY]<br />
GO<br />
SET ANSI_PADDING ON</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
&#8211; select * from [Security].[SalesAccess]    </p>
<p>UserID               TerritoryID<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; &#8212;&#8212;&#8212;&#8211;<br />
sordway              1<br />
sordway              2<br />
sordway              3<br />
bobama               1<br />
jmccain              2<br />
jkerry               6<br />
jkerry               7<br />
jkerry               8<br />
jkerry               9<br />
mromney              7<br />
mromney              8<br />
dbo                  1<br />
dbo                  2</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
&#8211; select * from [Security].[HRAccess]   </p>
<p>UserID               DepartmentID<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; &#8212;&#8212;&#8212;&#8212;<br />
bobama               4<br />
bobama               5<br />
bobama               6<br />
dbo                  5<br />
dbo                  6<br />
dbo                  7<br />
dbo                  8<br />
dbo                  9<br />
dbo                  10<br />
dbo                  11<br />
dbo                  12<br />
dbo                  13<br />
dbo                  14<br />
dbo                  15<br />
dbo                  16</p>
<p>(15 row(s) affected)</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
&#8211; table valued function accessing sales data joining to the sales security access table</p>
<p>USE [AdventureWorks]<br />
GO<br />
/****** Object:  UserDefinedFunction [Security].[ufnGetSalesTotals]    Script Date: 04/25/2009 12:25:48 ******/<br />
SET ANSI_NULLS ON<br />
GO<br />
SET QUOTED_IDENTIFIER ON<br />
GO</p>
<p>CREATE FUNCTION [Security].[ufnGetSalesTotals]<br />
(<br />
	@UserId VARCHAR(20)<br />
)<br />
RETURNS TABLE<br />
AS<br />
RETURN<br />
(<br />
	SELECT<br />
		pvt.[SalesPersonID]<br />
		,pvt.[FullName]<br />
		,pvt.[Title]<br />
		,pvt.[SalesTerritory]<br />
		,pvt.[2002]<br />
		,pvt.[2003]<br />
		,pvt.[2004]<br />
	FROM (SELECT<br />
			soh.[SalesPersonID]<br />
			,c.[FirstName] + &#8216; &#8216; + COALESCE(c.[MiddleName], &#8221;) + &#8216; &#8216; + c.[LastName] AS [FullName]<br />
			,e.[Title]<br />
			,st.[Name] AS [SalesTerritory]<br />
			,soh.[SubTotal]<br />
			,YEAR(DATEADD(m, 6, soh.[OrderDate])) AS [FiscalYear]<br />
		FROM [Sales].[SalesPerson] sp<br />
			INNER JOIN [Sales].[SalesOrderHeader] soh<br />
			ON sp.[SalesPersonID] = soh.[SalesPersonID]<br />
			INNER JOIN [Sales].[SalesTerritory] st<br />
			ON sp.[TerritoryID] = st.[TerritoryID]<br />
			INNER JOIN Security.SalesAccess sa   /* this is the added join */<br />
			ON sa.TerritoryID = st.[TerritoryID]<br />
			AND sa.UserId = @UserID<br />
			INNER JOIN [HumanResources].[Employee] e<br />
			ON soh.[SalesPersonID] = e.[EmployeeID]<br />
			INNER JOIN [Person].[Contact] c<br />
			ON e.[ContactID] = c.ContactID<br />
		) AS soh<br />
	PIVOT<br />
	(<br />
		SUM([SubTotal])<br />
		FOR [FiscalYear]<br />
		IN ([2002], [2003], [2004])<br />
	) AS pvt<br />
)</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
&#8211; View passing userid to the function above</p>
<p>USE [AdventureWorks]<br />
GO<br />
/****** Object:  View [Security].[vsSalesTotals]    Script Date: 04/25/2009 12:26:17 ******/<br />
SET ANSI_NULLS ON<br />
GO<br />
SET QUOTED_IDENTIFIER ON<br />
GO</p>
<p>CREATE VIEW [Security].[vsSalesTotals]<br />
AS<br />
SELECT<br />
		 [SalesPersonID]<br />
		,[FullName]<br />
		,[Title]<br />
		,[SalesTerritory]<br />
		,[2002]<br />
		,[2003]<br />
		,[2004] </p>
<p>FROM Security.ufnGetSalesTotals(USER)</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
&#8211; table valued function accessing employee data joining to the HR security access table</p>
<p>USE [AdventureWorks]<br />
GO<br />
/****** Object:  UserDefinedFunction [Security].[ufnGetEmployeeData]    Script Date: 04/25/2009 12:26:37 ******/<br />
SET ANSI_NULLS ON<br />
GO<br />
SET QUOTED_IDENTIFIER ON<br />
GO</p>
<p>CREATE FUNCTION [Security].[ufnGetEmployeeData]<br />
(<br />
	@UserId VARCHAR(20)<br />
)<br />
RETURNS TABLE<br />
AS<br />
RETURN<br />
(<br />
	SELECT<br />
		e.[EmployeeID]<br />
		,c.[Title]<br />
		,c.[FirstName]<br />
		,c.[MiddleName]<br />
		,c.[LastName]<br />
		,c.[Suffix]<br />
		,e.[Title] AS [JobTitle]<br />
		,edh.DepartmentID<br />
		,dpt.Name AS [DepartmentName]<br />
		,shr.UserID<br />
		,c.[Phone]<br />
		,c.[EmailAddress]<br />
		,c.[EmailPromotion]<br />
		,a.[AddressLine1]<br />
		,a.[AddressLine2]<br />
		,a.[City]<br />
		,sp.[Name] AS [StateProvinceName]<br />
		,a.[PostalCode]<br />
		,cr.[Name] AS [CountryRegionName]<br />
		,c.[AdditionalContactInfo]<br />
	FROM [HumanResources].[Employee] e<br />
		INNER JOIN [Person].[Contact] c<br />
		ON c.[ContactID] = e.[ContactID]<br />
		INNER JOIN [HumanResources].[EmployeeAddress] ea<br />
		ON e.[EmployeeID] = ea.[EmployeeID]<br />
		INNER JOIN [Person].[Address] a<br />
		ON ea.[AddressID] = a.[AddressID]<br />
		INNER JOIN [Person].[StateProvince] sp<br />
		ON sp.[StateProvinceID] = a.[StateProvinceID]<br />
		INNER JOIN [Person].[CountryRegion] cr<br />
		ON cr.[CountryRegionCode] = sp.[CountryRegionCode]<br />
		INNER JOIN HumanResources.EmployeeDepartmentHistory edh<br />
		ON edh.EmployeeID = e.EmployeeID<br />
		AND	edh.EndDate is null<br />
		INNER JOIN Security.HRAccess shr /* this is the added join */<br />
		ON shr.DepartmentID = edh.DepartmentID<br />
		and shr.UserID = @UserID<br />
		INNER JOIN HumanResources.Department dpt<br />
		ON dpt.DepartmentID = edh.DepartmentID<br />
)<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
&#8211; View passing userid to the function above</p>
<p>USE [AdventureWorks]<br />
GO<br />
/****** Object:  View [Security].[vsEmployee]    Script Date: 04/25/2009 12:27:01 ******/<br />
SET ANSI_NULLS ON<br />
GO<br />
SET QUOTED_IDENTIFIER ON<br />
GO</p>
<p>CREATE VIEW [Security].[vsEmployee]<br />
AS<br />
SELECT<br />
 		[EmployeeID]<br />
		,[Title]<br />
		,[FirstName]<br />
		,[MiddleName]<br />
		,[LastName]<br />
		,[Suffix]<br />
		,[JobTitle]<br />
		,DepartmentID<br />
		,[DepartmentName]<br />
		,UserID<br />
		,[Phone]<br />
		,[EmailAddress]<br />
		,[EmailPromotion]<br />
		,[AddressLine1]<br />
		,[AddressLine2]<br />
		,[City]<br />
		,[StateProvinceName]<br />
		,[PostalCode]<br />
		,[CountryRegionName]<br />
		,[AdditionalContactInfo]<br />
FROM Security.ufnGetEmployeeData(USER)</p>
<p>GO<br />
EXEC sys.sp_addextendedproperty @name=N&#8217;MS_Description&#8217;, @value=N&#8217;Employee names and addresses.&#8217; , @level0type=N&#8217;SCHEMA&#8217;,@level0name=N&#8217;Security&#8217;, @level1type=N&#8217;VIEW&#8217;,@level1name=N&#8217;vsEmployee&#8217;</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
&#8211; Presentation scripts</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
&#8211; Dr Dobbs Example 1: dbo<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>&#8211; Connect blambert</p>
<p>use rls</p>
<p>&#8211;The database includes these orders</p>
<p>select * from orders<br />
where department in (&#8216;East&#8217;, &#8216;Southeast&#8217;, &#8216;Northeast&#8217;)</p>
<p>&#8211;Here are the contents of the user access table<br />
select * from useraccess;</p>
<p>&#8211;and here are the results of a query summing orders accessible by<br />
&#8211; a particular user<br />
select * from getordersummary (&#8216;blambert&#8217;)</p>
<p>&#8211; here&#8217;s the view encapsulating the getordersummary function</p>
<p>select * from ordersummary</p>
<p>select user</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
&#8211; Dr Dobbs Example 2: mdavis<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>&#8211; Connect mdavis<br />
select user</p>
<p>use rls</p>
<p>&#8211;review the orders table</p>
<p>select * from orders<br />
where department in (&#8216;East&#8217;, &#8216;Southeast&#8217;, &#8216;Northeast&#8217;)</p>
<p>&#8211;review the user access table<br />
select * from useraccess;</p>
<p>&#8211;review the getordersummary table-valued function<br />
select * from getordersummary (&#8216;mdavis&#8217;)</p>
<p>&#8211; review the ordersummary view</p>
<p>select * from ordersummary</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
&#8211; AdventureWorks Example 1: dbo<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>&#8211; Connect blambert</p>
<p>use AdventureWorks</p>
<p>&#8211;Adventureworks includes this view, providing a pivoted sales report</p>
<p>select * from Sales.vSalesPersonSalesByFiscalYears </p>
<p>&#8211;Here are the contents of the user access table</p>
<p>select * from Security.SalesAccess</p>
<p>&#8211;Here are territory codes</p>
<p>select * from Sales.SalesTerritory</p>
<p>&#8211;and here are the results of a query summing orders accessible by<br />
&#8211; a particular user<br />
select * from Security.ufnGetSalesTotals(&#8216;jmccain&#8217;)</p>
<p>&#8211; here&#8217;s the view encapsulating the getordersummary function</p>
<p>select * from Security.vsSalesTotals</p>
<p>select user</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
&#8211; AdventureWorks Example 1: bobama<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>&#8211; Connect bobama</p>
<p>use AdventureWorks</p>
<p>&#8211;Adventureworks includes this view, providing a pivoted sales report</p>
<p>select * from Sales.vSalesPersonSalesByFiscalYears </p>
<p>&#8211;Here are the contents of the user access table</p>
<p>select * from Security.SalesAccess</p>
<p>&#8211;Here are territory codes</p>
<p>select * from Sales.SalesTerritory</p>
<p>&#8211;and here are the results of a query summing orders accessible by<br />
&#8211; a particular user<br />
select * from Security.ufnGetSalesTotals(&#8216;bobama&#8217;)</p>
<p>&#8211; here&#8217;s the view encapsulating the getordersummary function</p>
<p>select * from Security.vsSalesTotals</p>
<p>select user</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
&#8211; AdventureWorks Example 2: dbo<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>&#8211; Connect blambert</p>
<p>use AdventureWorks</p>
<p>&#8211;Adventureworks includes this view, providing employee data</p>
<p>select * from HumanResources.vEmployee </p>
<p>&#8211;Here are the contents of the user access table</p>
<p>select * from Security.HRAccess</p>
<p>&#8211;Here are department ids</p>
<p>select * from HumanResources.Department<br />
select * from HumanResources.EmployeeDepartmentHistory where enddate is null</p>
<p>&#8211;and here are the results of a query summing using the table valued function to list employees</p>
<p>select * from Security.ufnGetEmployeeData(&#8216;jmccain&#8217;)</p>
<p>&#8211; here&#8217;s the view encapsulating the ufnGetEmployeeData function</p>
<p>select * from Security.vsEmployee</p>
<p>select user<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
&#8211; AdventureWorks Example 2: bobama<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>&#8211; Connect bobama</p>
<p>use AdventureWorks</p>
<p>&#8211;Adventureworks includes this view, providing employee data</p>
<p>select * from HumanResources.vEmployee </p>
<p>&#8211;Here are the contents of the user access table</p>
<p>select * from Security.HRAccess</p>
<p>&#8211;Here are department ids</p>
<p>select * from HumanResources.Department<br />
select * from HumanResources.EmployeeDepartmentHistory where enddate is null</p>
<p>&#8211;and here are the results of a query summing using the table valued function to list employees</p>
<p>select * from Security.ufnGetEmployeeData(&#8216;jmccain&#8217;)</p>
<p>&#8211; here&#8217;s the view encapsulating the ufnGetEmployeeData function</p>
<p>select * from Security.vsEmployee</p>
<p>select user</p>
]]></content:encoded>
	</item>
</channel>
</rss>
