Showing posts with label members. Show all posts
Showing posts with label members. Show all posts

Wednesday, March 7, 2012

Can I Use Non-empty Behavior for These Calculated Members?

I still find myself extremely confused about using the non-empty behavior for calculated members.

We have a series of calculated members that we refer to as "Velocity", such as "Velocity Sales". The basic definition for these velocity measures is to get the total from the previous 63 business days and then annualize that total (i.e. multiply by 4), with the 63rd business day belonging to the previous month.

For example, Velocity Sales for any day in September 2006 would be totaling the sales $ for the business days in the range of 06/05/2006 through 08/31/2006, and then multiplying it by 4. Perhaps not surprisingly, these measures result in extremely poor performance.

Since I'm confused on the non-empty behavior, this property has not been set on any of the velocity measures.

Therefore, can I set the non-empty behavior for my velocity measures without risk of erroneous data? Based on extremely limited testing, enabling this property doesn't seem to cause any erroneous data, but I want to be confident before deploying it. Of course, enabling it results in a huge performance gain.

Below is the the definition for the [Velocity Sales] calculated member, just in case it can be of use:

SUM(Filter(Head(Tail(Filter({[Date].[Date].[Date].Members.Item(0).Item(0):Tail(Exists([Date].[Date].[Date].Members,
Tail(Existing [Date].[Month].[Month].Members,1).Item(0).Item(0).Lag(1)),1).Item(0).Item(0)},
[Date].[CP Business Day Indicator].MemberValue = 1),63),1).Item(0).Item(0)
:
Tail(Filter({[Date].[Date].[Date].Members.Item(0).Item(0):Tail(Exists([Date].[Date].[Date].Members,
Tail(Existing [Date].[Month].[Month].Members,1).Item(0).Item(0).Lag(1)),1).Item(0).Item(0)},
[Date].[CP Business Day Indicator].MemberValue = 1),1).Item(0).Item(0),[Date].[CP Business Day Indicator].MemberValue = 1),[Measures].[Sales USD])*4

I would really appreciate some insight!

Setting the Non Empty Behavior of the calculated measure above to, say, [Measures].[Sales USD] certainly wouldn't make sense, because there might be no sales on a given day (like a Sunday), yet the 63 prior business days considered for that day's velocity might well have sales.

If sparse cube data is a performance issue, you could apply NonEmpty() to the set of 63 days above, to filter out days with no data. Another obvious improvement would be to directly specify a CP Business Day Indicator attribute member, rather than applying Filter() with the "[Date].[CP Business Day Indicator].MemberValue = 1" condition - as also discussed in this paper:

http://www.sqlserveranalysisservices.com/OLAPPapers/MDX%20Performance%20Hintsv1.htm

>>

Use your attributes!

In SQL Server Analysis Services 2000, the filter function was a common means of selecting members from a set whose member property satisfied some condition; for example male customers could be expressed as :

Filter(Customer.name.Name.members, Customer.name.currentmember.properties(“Gender”) = “Male”)

Don’t do this in SQL Server Analysis Services 2005. Instead, create an attribute hierarchy Customers.Gender.Male and do this:

(Customers.Gender.Male, Measures.Sales)

Use NonEmpty Function

The NonEmpty function (new in SQL Server Analysis Services 2005) is optimized for removing empty tuples. So instead of doing this to get the customers who bought an Xbox,

Filter(Customer.Name.members, not IsEmpty( ([Measures].[Unit Sales], [Product].[Name].[Xbox])

Do this:

NonEmpty (Customer.Name.members, ([Measures].[Unit Sales], [Product].[Name].[Xbox]))

>>

|||Thanks for the suggestions. However, I still have a few questions.

I implemented the following hierarchy called BusinessDays in my Date dimension that consists of:

[CP Business Day Indicator]
Month
Date (dimension key)

As a result, [Velocity Sales $] has now been defined as:

SUM(LASTPERIODS(63,TAIL(EXISTING BusinessDays.Month.MEMBERS).ITEM(0).ITEM(0).LAG(1).LASTCHILD),[Measures].[Sales USD])*4

Unfortunately, I don't see any dramatic performance improvemenst with this approach. Of course, setting the Non-empty behavior property to [Measures].[Sales USD] makes a world of a difference.

I see what you're saying as to why setting the Non-empty behavior property doesn't seem to make sense, but based on further testing scenarios, I have not seen any erroneous data yet -- I have 2 measures that are defined the same, with one having the Non-empty behavior property set while the other one doesn't.

|||

Based on my understanding of Non Empty Behavior, I can't suggest using it here. For example, using Adventure Works:

>>

With

Member [Measures].[PrevMonthSales1] as

([Measures].[Sales Amount],

(Existing [Date].[Calendar].[Month]).item(0).item(0).Lag(1))

Member [Measures].[PrevMonthSales2] as

([Measures].[Sales Amount],

(Existing [Date].[Calendar].[Month]).item(0).item(0).Lag(1)),

NON_EMPTY_BEHAVIOR = '[Measures].[Sales Amount]'

select {[Measures].[Sales Amount],

[Measures].[PrevMonthSales1],

[Measures].[PrevMonthSales2]} on 0,

{[Date].[Calendar].[Month].&[2004]&Devil,

[Date].[Calendar].[Date].&[1106]} on 1

from [Adventure Works]

where [Product].[Product Categories].[Subcategory].&[19]

-

Sales Amount PrevMonthSales1 PrevMonthSales2
June 2004 $3,276.23 3157.57929999999 3157.57929999999
July 10, 2004 (null) 3276.22569999999 (null)

>>

Did you try to see if NonEmpty() can help performance - like:

SUM(NonEmpty(LASTPERIODS(63,

TAIL(EXISTING BusinessDays.Month.MEMBERS).ITEM(0).ITEM(0).LAG(1).LASTCHILD),

{[Measures].[Sales USD]}), [Measures].[Sales USD])*4

|||

Deepak Puri wrote:

>>

Use your attributes!

In SQL Server Analysis Services 2000, the filter function was a common means of selecting members from a set whose member property satisfied some condition; for example male customers could be expressed as :

Filter(Customer.name.Name.members, Customer.name.currentmember.properties(“Gender”) = “Male”)

Don’t do this in SQL Server Analysis Services 2005. Instead, create an attribute hierarchy Customers.Gender.Male and do this:

(Customers.Gender.Male, Measures.Sales)

Using this method how could I combine multiple filters in the same set? For example I might want to include all males together with a hair colour brown. I would get dimenstionality errors if I set up different hierarchies for different attributes and then tried to combine them.

|||

Using this method how could I combine multiple filters in the same set? For example I might want to include all males together with a hair colour brown. I would get dimenstionality errors if I set up different hierarchies for different attributes and then tried to combine them

(Customers.Gender.Male, Customers.HairColor.Brown) - this won't give you any dimensionality errors since Gender and HairColor are different attributes.

HTH,

Mosha (http://www.mosha.com/msolap)

|||

I can get:

({[Product].[Product Hierarchy].[Product Group Level 1].&[Product Group] * [Product].[My Flag].[True])

to work but not:

({[Product].[Product Hierarchy].[Product Group Level 1].&[Product Group], [Product].[My Flag].[True])

Is this what you'd expect? Is it not possible to combine user defined hierarchies with attribute hierarchies?

Thanks.

|||

Well - in both expressions you have extra { at the beginning - so none of them will pass syntax check, but other then that - looks like the first one will simply multiply the values, whereas the second one will construct the actual tuple. The second one should work - you can combine any hierarchies together in the tuple. Can you please give a complete example, preferably using Adventure Works for reproducability of your issue.

Thanks,

Mosha

|||

This doesn't work for me. I get a dimensionality error. I'm sure I'm missing something obvious. If you could point me in the right direction I'd be grateful.

SELECT { [Date].[Calendar].DEFAULTMEMBER } ON COLUMNS ,

{[Product].[Style].[Unisex], [Product].[Product Categories].[Subcategory].[Mountain Bikes] } ON ROWS

FROM [Adventure Works]

WHERE ( [Measures].[Sales Amount])

|||

To build a tuple you need to use ()'s not {}'s, i.e.

SELECT { [Date].[Calendar].DEFAULTMEMBER } ON COLUMNS ,

([Product].[Style].[Unisex], [Product].[Product Categories].[Subcategory].[Mountain Bikes] ) ON ROWS

FROM [Adventure Works]

WHERE ( [Measures].[Sales Amount])

HTH

Mosha (http://www.mosha.com/msolap)

|||That does the trick. Thanks v much.|||

One more question. How can I reproduce this for sets? This code works. It doesn't work if I remove Filter from the beginning.

Filter([Product].[Product Hierarchy].[Product Grouping].[MyProduct].children, [Product].[Product Flag].[True])

|||

Use the following:

Exists([Product].[Product Hierarchy].[Product Grouping].[MyProduct].children, [Product].[Product Flag].[True])

|||Doesn't return the same results as I get using Filter. I can stick with Filter.|||

Of course it doesn't return same results as with Filter. Your Filter looks at cell values where Flag.True member evaluates cell value to Non-zero. I was under impression that you didn't want to look at cell values, but at dimension table and only return products which have Flag set to True.

HTH,

Mosha (http://www.mosha.com/msolap)

Can I Use Non-empty Behavior for These Calculated Members?

I still find myself extremely confused about using the non-empty behavior for calculated members.

We have a series of calculated members that we refer to as "Velocity", such as "Velocity Sales". The basic definition for these velocity measures is to get the total from the previous 63 business days and then annualize that total (i.e. multiply by 4), with the 63rd business day belonging to the previous month.

For example, Velocity Sales for any day in September 2006 would be totaling the sales $ for the business days in the range of 06/05/2006 through 08/31/2006, and then multiplying it by 4. Perhaps not surprisingly, these measures result in extremely poor performance.

Since I'm confused on the non-empty behavior, this property has not been set on any of the velocity measures.

Therefore, can I set the non-empty behavior for my velocity measures without risk of erroneous data? Based on extremely limited testing, enabling this property doesn't seem to cause any erroneous data, but I want to be confident before deploying it. Of course, enabling it results in a huge performance gain.

Below is the the definition for the [Velocity Sales] calculated member, just in case it can be of use:

SUM(Filter(Head(Tail(Filter({[Date].[Date].[Date].Members.Item(0).Item(0):Tail(Exists([Date].[Date].[Date].Members,
Tail(Existing [Date].[Month].[Month].Members,1).Item(0).Item(0).Lag(1)),1).Item(0).Item(0)},
[Date].[CP Business Day Indicator].MemberValue = 1),63),1).Item(0).Item(0)
:
Tail(Filter({[Date].[Date].[Date].Members.Item(0).Item(0):Tail(Exists([Date].[Date].[Date].Members,
Tail(Existing [Date].[Month].[Month].Members,1).Item(0).Item(0).Lag(1)),1).Item(0).Item(0)},
[Date].[CP Business Day Indicator].MemberValue = 1),1).Item(0).Item(0),[Date].[CP Business Day Indicator].MemberValue = 1),[Measures].[Sales USD])*4

I would really appreciate some insight!

Setting the Non Empty Behavior of the calculated measure above to, say, [Measures].[Sales USD] certainly wouldn't make sense, because there might be no sales on a given day (like a Sunday), yet the 63 prior business days considered for that day's velocity might well have sales.

If sparse cube data is a performance issue, you could apply NonEmpty() to the set of 63 days above, to filter out days with no data. Another obvious improvement would be to directly specify a CP Business Day Indicator attribute member, rather than applying Filter() with the "[Date].[CP Business Day Indicator].MemberValue = 1" condition - as also discussed in this paper:

http://www.sqlserveranalysisservices.com/OLAPPapers/MDX%20Performance%20Hintsv1.htm

>>

Use your attributes!

In SQL Server Analysis Services 2000, the filter function was a common means of selecting members from a set whose member property satisfied some condition; for example male customers could be expressed as :

Filter(Customer.name.Name.members, Customer.name.currentmember.properties(“Gender”) = “Male”)

Don’t do this in SQL Server Analysis Services 2005. Instead, create an attribute hierarchy Customers.Gender.Male and do this:

(Customers.Gender.Male, Measures.Sales)

Use NonEmpty Function

The NonEmpty function (new in SQL Server Analysis Services 2005) is optimized for removing empty tuples. So instead of doing this to get the customers who bought an Xbox,

Filter(Customer.Name.members, not IsEmpty( ([Measures].[Unit Sales], [Product].[Name].[Xbox])

Do this:

NonEmpty (Customer.Name.members, ([Measures].[Unit Sales], [Product].[Name].[Xbox]))

>>

|||Thanks for the suggestions. However, I still have a few questions.

I implemented the following hierarchy called BusinessDays in my Date dimension that consists of:

[CP Business Day Indicator]
Month
Date (dimension key)

As a result, [Velocity Sales $] has now been defined as:

SUM(LASTPERIODS(63,TAIL(EXISTING BusinessDays.Month.MEMBERS).ITEM(0).ITEM(0).LAG(1).LASTCHILD),[Measures].[Sales USD])*4

Unfortunately, I don't see any dramatic performance improvemenst with this approach. Of course, setting the Non-empty behavior property to [Measures].[Sales USD] makes a world of a difference.

I see what you're saying as to why setting the Non-empty behavior property doesn't seem to make sense, but based on further testing scenarios, I have not seen any erroneous data yet -- I have 2 measures that are defined the same, with one having the Non-empty behavior property set while the other one doesn't.

|||

Based on my understanding of Non Empty Behavior, I can't suggest using it here. For example, using Adventure Works:

>>

With

Member [Measures].[PrevMonthSales1] as

([Measures].[Sales Amount],

(Existing [Date].[Calendar].[Month]).item(0).item(0).Lag(1))

Member [Measures].[PrevMonthSales2] as

([Measures].[Sales Amount],

(Existing [Date].[Calendar].[Month]).item(0).item(0).Lag(1)),

NON_EMPTY_BEHAVIOR = '[Measures].[Sales Amount]'

select {[Measures].[Sales Amount],

[Measures].[PrevMonthSales1],

[Measures].[PrevMonthSales2]} on 0,

{[Date].[Calendar].[Month].&[2004]&Devil,

[Date].[Calendar].[Date].&[1106]} on 1

from [Adventure Works]

where [Product].[Product Categories].[Subcategory].&[19]

-

Sales Amount PrevMonthSales1 PrevMonthSales2
June 2004 $3,276.23 3157.57929999999 3157.57929999999
July 10, 2004 (null) 3276.22569999999 (null)

>>

Did you try to see if NonEmpty() can help performance - like:

SUM(NonEmpty(LASTPERIODS(63,

TAIL(EXISTING BusinessDays.Month.MEMBERS).ITEM(0).ITEM(0).LAG(1).LASTCHILD),

{[Measures].[Sales USD]}), [Measures].[Sales USD])*4

|||

Deepak Puri wrote:

>>

Use your attributes!

In SQL Server Analysis Services 2000, the filter function was a common means of selecting members from a set whose member property satisfied some condition; for example male customers could be expressed as :

Filter(Customer.name.Name.members, Customer.name.currentmember.properties(“Gender”) = “Male”)

Don’t do this in SQL Server Analysis Services 2005. Instead, create an attribute hierarchy Customers.Gender.Male and do this:

(Customers.Gender.Male, Measures.Sales)

Using this method how could I combine multiple filters in the same set? For example I might want to include all males together with a hair colour brown. I would get dimenstionality errors if I set up different hierarchies for different attributes and then tried to combine them.

|||

Using this method how could I combine multiple filters in the same set? For example I might want to include all males together with a hair colour brown. I would get dimenstionality errors if I set up different hierarchies for different attributes and then tried to combine them

(Customers.Gender.Male, Customers.HairColor.Brown) - this won't give you any dimensionality errors since Gender and HairColor are different attributes.

HTH,

Mosha (http://www.mosha.com/msolap)

|||

I can get:

({[Product].[Product Hierarchy].[Product Group Level 1].&[Product Group] * [Product].[My Flag].[True])

to work but not:

({[Product].[Product Hierarchy].[Product Group Level 1].&[Product Group], [Product].[My Flag].[True])

Is this what you'd expect? Is it not possible to combine user defined hierarchies with attribute hierarchies?

Thanks.

|||

Well - in both expressions you have extra { at the beginning - so none of them will pass syntax check, but other then that - looks like the first one will simply multiply the values, whereas the second one will construct the actual tuple. The second one should work - you can combine any hierarchies together in the tuple. Can you please give a complete example, preferably using Adventure Works for reproducability of your issue.

Thanks,

Mosha

|||

This doesn't work for me. I get a dimensionality error. I'm sure I'm missing something obvious. If you could point me in the right direction I'd be grateful.

SELECT { [Date].[Calendar].DEFAULTMEMBER } ON COLUMNS ,

{[Product].[Style].[Unisex], [Product].[Product Categories].[Subcategory].[Mountain Bikes] } ON ROWS

FROM [Adventure Works]

WHERE ( [Measures].[Sales Amount])

|||

To build a tuple you need to use ()'s not {}'s, i.e.

SELECT { [Date].[Calendar].DEFAULTMEMBER } ON COLUMNS ,

([Product].[Style].[Unisex], [Product].[Product Categories].[Subcategory].[Mountain Bikes] ) ON ROWS

FROM [Adventure Works]

WHERE ( [Measures].[Sales Amount])

HTH

Mosha (http://www.mosha.com/msolap)

|||That does the trick. Thanks v much.|||

One more question. How can I reproduce this for sets? This code works. It doesn't work if I remove Filter from the beginning.

Filter([Product].[Product Hierarchy].[Product Grouping].[MyProduct].children, [Product].[Product Flag].[True])

|||

Use the following:

Exists([Product].[Product Hierarchy].[Product Grouping].[MyProduct].children, [Product].[Product Flag].[True])

|||Doesn't return the same results as I get using Filter. I can stick with Filter.|||

Of course it doesn't return same results as with Filter. Your Filter looks at cell values where Flag.True member evaluates cell value to Non-zero. I was under impression that you didn't want to look at cell values, but at dimension table and only return products which have Flag set to True.

HTH,

Mosha (http://www.mosha.com/msolap)

Thursday, February 16, 2012

Can I restrict members of db_datareader from SELECTing from a tabl

I have a large database with lost of users, many of whom are in the
db_datareader role.
I have a table that I want to restrict SELECTs on to just sa's.
How can I restrict members of db_datareader from SELECTing from this table?
As shown below, I cannot REVOKE or DENY SELECT from this role.
I could remove everyone from db_datareader and put them in a special role
with SELECT on everything but this table. But is there an easier way?
Thanks
USE admin
CREATE TABLE myTable
(col1 int PRIMARY KEY IDENTITY
,col2 int
,col3 int)
INSERT myTable (col2) VALUES (10)
INSERT myTable (col2) VALUES (20)
INSERT myTable (col2) VALUES (30)
SELECT * FROM myTable
execute as login = 'appuser'
select suser_name()
SELECT * FROM myTable
revert
sp_helprolemember db_datareader
REVOKE SELECT ON myTable TO db_datareader
--Cannot grant, deny or revoke permissions to or from special roles.
DENY SELECT ON myTable TO db_datareader
Hello,
You can not attempt to issue a DENY or REVOKE on to a fixed role.Issue the
DENY SELECT statement on to all uses who are not supposed to
query the table and see if that works well.
THanks
Hari
"Dave" <Dave@.discussions.microsoft.com> wrote in message
news:B4980135-A8AE-4D4B-8B11-2623407D8986@.microsoft.com...
>I have a large database with lost of users, many of whom are in the
> db_datareader role.
> I have a table that I want to restrict SELECTs on to just sa's.
> How can I restrict members of db_datareader from SELECTing from this
> table?
> As shown below, I cannot REVOKE or DENY SELECT from this role.
> I could remove everyone from db_datareader and put them in a special role
> with SELECT on everything but this table. But is there an easier way?
> Thanks
> --
> USE admin
> CREATE TABLE myTable
> (col1 int PRIMARY KEY IDENTITY
> ,col2 int
> ,col3 int)
> INSERT myTable (col2) VALUES (10)
> INSERT myTable (col2) VALUES (20)
> INSERT myTable (col2) VALUES (30)
> SELECT * FROM myTable
> execute as login = 'appuser'
> select suser_name()
> SELECT * FROM myTable
> revert
> sp_helprolemember db_datareader
> REVOKE SELECT ON myTable TO db_datareader
> --Cannot grant, deny or revoke permissions to or from special roles.
> DENY SELECT ON myTable TO db_datareader
>
>
|||Hi Dave
"Dave" wrote:

> I have a large database with lost of users, many of whom are in the
> db_datareader role.
> I have a table that I want to restrict SELECTs on to just sa's.
>
It sounds like you need to make your security more granular, by creating
your own role(s) that only have the permissions the users actually need. You
could also do this using Windows Groups (or a combination of both!) if you
are using Windows Authentication. By only using Stored Procedures to access
your data it may be possible to limit who can SELECT from a table further.
John

Can I restrict members of db_datareader from SELECTing from a tabl

I have a large database with lost of users, many of whom are in the
db_datareader role.
I have a table that I want to restrict SELECTs on to just sa's.
How can I restrict members of db_datareader from SELECTing from this table?
As shown below, I cannot REVOKE or DENY SELECT from this role.
I could remove everyone from db_datareader and put them in a special role
with SELECT on everything but this table. But is there an easier way?
Thanks
--
USE admin
CREATE TABLE myTable
(col1 int PRIMARY KEY IDENTITY
,col2 int
,col3 int)
INSERT myTable (col2) VALUES (10)
INSERT myTable (col2) VALUES (20)
INSERT myTable (col2) VALUES (30)
SELECT * FROM myTable
execute as login = 'appuser'
select suser_name()
SELECT * FROM myTable
revert
sp_helprolemember db_datareader
REVOKE SELECT ON myTable TO db_datareader
--Cannot grant, deny or revoke permissions to or from special roles.
DENY SELECT ON myTable TO db_datareaderHello,
You can not attempt to issue a DENY or REVOKE on to a fixed role.Issue the
DENY SELECT statement on to all uses who are not supposed to
query the table and see if that works well.
THanks
Hari
"Dave" <Dave@.discussions.microsoft.com> wrote in message
news:B4980135-A8AE-4D4B-8B11-2623407D8986@.microsoft.com...
>I have a large database with lost of users, many of whom are in the
> db_datareader role.
> I have a table that I want to restrict SELECTs on to just sa's.
> How can I restrict members of db_datareader from SELECTing from this
> table?
> As shown below, I cannot REVOKE or DENY SELECT from this role.
> I could remove everyone from db_datareader and put them in a special role
> with SELECT on everything but this table. But is there an easier way?
> Thanks
> --
> USE admin
> CREATE TABLE myTable
> (col1 int PRIMARY KEY IDENTITY
> ,col2 int
> ,col3 int)
> INSERT myTable (col2) VALUES (10)
> INSERT myTable (col2) VALUES (20)
> INSERT myTable (col2) VALUES (30)
> SELECT * FROM myTable
> execute as login = 'appuser'
> select suser_name()
> SELECT * FROM myTable
> revert
> sp_helprolemember db_datareader
> REVOKE SELECT ON myTable TO db_datareader
> --Cannot grant, deny or revoke permissions to or from special roles.
> DENY SELECT ON myTable TO db_datareader
>
>|||Hi Dave
"Dave" wrote:
> I have a large database with lost of users, many of whom are in the
> db_datareader role.
> I have a table that I want to restrict SELECTs on to just sa's.
>
It sounds like you need to make your security more granular, by creating
your own role(s) that only have the permissions the users actually need. You
could also do this using Windows Groups (or a combination of both!) if you
are using Windows Authentication. By only using Stored Procedures to access
your data it may be possible to limit who can SELECT from a table further.
John

Can I restrict members of db_datareader from SELECTing from a tabl

I have a large database with lost of users, many of whom are in the
db_datareader role.
I have a table that I want to restrict SELECTs on to just sa's.
How can I restrict members of db_datareader from SELECTing from this table?
As shown below, I cannot REVOKE or DENY SELECT from this role.
I could remove everyone from db_datareader and put them in a special role
with SELECT on everything but this table. But is there an easier way?
Thanks
USE admin
CREATE TABLE myTable
(col1 int PRIMARY KEY IDENTITY
,col2 int
,col3 int)
INSERT myTable (col2) VALUES (10)
INSERT myTable (col2) VALUES (20)
INSERT myTable (col2) VALUES (30)
SELECT * FROM myTable
execute as login = 'appuser'
select suser_name()
SELECT * FROM myTable
revert
sp_helprolemember db_datareader
REVOKE SELECT ON myTable TO db_datareader
--Cannot grant, deny or revoke permissions to or from special roles.
DENY SELECT ON myTable TO db_datareaderHello,
You can not attempt to issue a DENY or REVOKE on to a fixed role.Issue the
DENY SELECT statement on to all uses who are not supposed to
query the table and see if that works well.
THanks
Hari
"Dave" <Dave@.discussions.microsoft.com> wrote in message
news:B4980135-A8AE-4D4B-8B11-2623407D8986@.microsoft.com...
>I have a large database with lost of users, many of whom are in the
> db_datareader role.
> I have a table that I want to restrict SELECTs on to just sa's.
> How can I restrict members of db_datareader from SELECTing from this
> table?
> As shown below, I cannot REVOKE or DENY SELECT from this role.
> I could remove everyone from db_datareader and put them in a special role
> with SELECT on everything but this table. But is there an easier way?
> Thanks
> --
> USE admin
> CREATE TABLE myTable
> (col1 int PRIMARY KEY IDENTITY
> ,col2 int
> ,col3 int)
> INSERT myTable (col2) VALUES (10)
> INSERT myTable (col2) VALUES (20)
> INSERT myTable (col2) VALUES (30)
> SELECT * FROM myTable
> execute as login = 'appuser'
> select suser_name()
> SELECT * FROM myTable
> revert
> sp_helprolemember db_datareader
> REVOKE SELECT ON myTable TO db_datareader
> --Cannot grant, deny or revoke permissions to or from special roles.
> DENY SELECT ON myTable TO db_datareader
>
>|||Hi Dave
"Dave" wrote:

> I have a large database with lost of users, many of whom are in the
> db_datareader role.
> I have a table that I want to restrict SELECTs on to just sa's.
>
It sounds like you need to make your security more granular, by creating
your own role(s) that only have the permissions the users actually need. You
could also do this using Windows Groups (or a combination of both!) if you
are using Windows Authentication. By only using Stored Procedures to access
your data it may be possible to limit who can SELECT from a table further.
John