March 21, 2003 at 1:17 pm
I want to be wrong - please tell me I am mistaken
I am trying to use Table Function to filter data based on rights. According to rules set up in other tables, the table function returns a True or False that a given person can access a specific object. I.E.
--Function definition
CREATE FUNCTION faCanAccessObject (
@personID INT,
@objectID INT
) RETURNS @AccessRights TABLE (
CanAccess TINYINT
) AS
BEGIN
INSERT INTO @AccessRights
<Lots of code>
RETURN
END
I would like to do this:
SELECT P.PName, D.DocumentName, A.CanAccess
FROM Person P,
INNER JOIN Document D ON 1=1
INNER JOIN faCanAccessObject( P.PersonID, D.DocID ) A
There will be an incredibily huge volume so it needs to be a subselect and not the main table (85 million rows - 100,000+ requests per day)
Ideas?
Thanks
Guarddata-
March 21, 2003 at 1:28 pm
You don't want to use : PERMISSIONS() from T-SQL?
Tim C.
//Will write code for food
Tim C //Will code for food
March 21, 2003 at 1:49 pm
I may not be understanding the PERMISSIONS function, but was under the impression that is only identifies that I have rights to select from the Database Table. I need data level access where some items can be selected and others can't based on group membership and other rules.
TABLE - Document
TABLE - Members of a group
TABLE - DocsRights ( DocID, GroupID )
SELECT D.DocName, R.CanAccess
FROM Document D
INNER JOIN DocRights( PersonID, D.DocID) R
WHERE ( D.CreateDate + 7 ) > GetDate()
Enough info?
Guarddata-
March 21, 2003 at 2:55 pm
based upon from BOL :
quote:
Bit (dec) Bit (hex) Statement permission1 0x1 SELECT ALL
2 0x2 UPDATE ALL
4 0x4 REFERENCES ALL
8 0x8 INSERT
16 0x10 DELETE
32 0x20 EXECUTE (procedures only)
4096 0x1000 SELECT ANY (at least one column)
8192 0x2000 UPDATE ANY
16384 0x4000 REFERENCES ANY
and your query, Would
SELECT D.DocName
FROM Document D
WHERE PERMISSIONS(OBJECT_ID('Document'))&1=1
AND (D.CreateDate + 7) > GetDate()
Not work for you? It even take an optional second parameter for the column, so you could test column permissions.
Tim C.
//Will write code for food
Tim C //Will code for food
March 21, 2003 at 3:01 pm
Kind of a different need I think.
Consider this:
CREATE TABLE Document (
DocID INT,
DocName VARCHAR(30)
)
INSERT INTO Document VALUES ( 1, 'First Test' )
INSERT INTO Document VALUES ( 2, 'Second Test' )
INSERT INTO Document VALUES ( 3, 'Third Test' )
My rules are set so that I can access #s 1 and 3 but not 2.
Can the PERMISSIONS function still resolve this?
Guarddata-
March 21, 2003 at 3:26 pm
I see said the blind man. Interesting issue. How do you store the permissions? Can you post the DDL? I have never tried to do row permissions before... I'm actually at a loss to think of a clean / fast way to do this. Hopefully the gurus on this site can help. Sorry guard.
Tim C.
//Will write code for food
Tim C //Will code for food
March 21, 2003 at 3:40 pm
It would take about 3 pages to fully describe the process (and this thread is getting close )
The permission rules are in a table like:
TABLE permissions
ObjectID INT, --Document being secured
IsPerson TINYINT, --Person can override group settings
SecureID INT, --ID of the person or group
SeeRights,
ChgRights,
DelRights
The Rights are TINYINT values. 1 means Grant, 2=Revoke, NULL (for Person only) accept group setting.
I can write a function that gives me the result I need - but cannot join it. For now, I will probably just create a trigger that produces the privileges when the rule is changed and keeps it in a table used for the joins. A bit messy - but probably better in the long run since permissions should change that much.
Thanks for looking at it.
Guarddata-
March 21, 2003 at 4:10 pm
Ok, you can join a table UDF to a query. Try this :
USE PUBS
GO
IF EXISTS (SELECT *
FROM sysobjects
WHERE name = N'fnPubsSyobjectsTable')
DROP FUNCTION fnPubsSyobjectsTable
GO
CREATE FUNCTION fnPubsSyobjectsTable()
RETURNS @table_var TABLE(name sysname,
id int)
AS
BEGIN
INSERT INTO @table_var
SELECT name, id
FROM sysobjects
RETURN
END
GO
SELECT SO.name As SOname,
PSO.name As PSOname
FROM sysobjects SO
INNER JOIN [dbo].[fnPubsSyobjectsTable]() PSO
ON SO.id = PSO.id
DROP FUNCTION fnPubsSyobjectsTable
Hope this helps with the main question you had, Sorry for the tangent.
Tim C.
//Will write code for food
Tim C //Will code for food
March 21, 2003 at 4:30 pm
Thanks for taking the time on this one Tim.
Yes - I can join in the way you describe. I was just nervous about the efficiency - probably my lack of experience with the defined tables. My first impressions where that the defined table would be created like a temporary table, then joined - so I wanted the smallest result set possible.
It appears that SQL is better than that so I will run some tests and go from there.
Thanks again
Guarddata-
March 22, 2003 at 7:31 pm
Guard I think I did you a disservice by misunderstanding your initial question, and going off post with my answers. I apologize. As to your question I have seen a couple threads on these forums about UDF's and efficiency, and I will try to find them for you. Having never done a study on them myself I am going to bump this post up to the experts otherwise.
Tim C.
//Will write code for food
Tim C //Will code for food
Viewing 10 posts - 1 through 9 (of 9 total)
You must be logged in to reply to this topic. Login to reply