从表中选择与同一行相关但仅显示允许字段的字段

时间:2010-12-29 10:07:12

标签: sql-server-2005 tsql sql-server-2008

嗨,我有这个表的字段:Employees

id,firstname,lastname,birthdate

我想在某些字段上隐私,所以我创建了包含这些字段的表

tableName,ColumnName,PrivacyType [Visible / Notvisible]

当从第一个表中选择一行时,我不想获得具有的字段 隐私类型= NotVisible

任何想法

2 个答案:

答案 0 :(得分:0)

好吧,就像我讨厌动态sql一样,我想不出一种方法可以在没有它的情况下做你想做的事。我强烈建议您考虑通过其他方式设计数据库或让其他应用程序解决隐私列来实现您想要的另一种方式。无论如何,你可以用动态sql做的事情。

DECLARE @Table VARCHAR(100) @Columns VARCHAR(MAX), @Query VARCHAR(MAX)
SET @Columns = ''
SET @Table = 'Employees'

SELECT @Columns = @Columns + '[' + A.COLUMN_NAME + '],'
FROM INFORMATION_SCHEMA.COLUMNS A
INNER JOIN PrivacyTable B
A.TABLE_NAME = B.TableName AND A.COLUMN_NAME = B.ColumnName
WHERE A.TABLE_NAME = @Table AND B.PrivacyType = 'Visible'
ORDER BY A.ORDINAL_POSITION

SET @Columns = LEFT(@Columns,LEN(@Columns)-1)

SET @Query = 'SELECT ' + @Columns + ' FROM [' + @Table + ']'

EXEC(@Query)

答案 1 :(得分:0)

通常,如果您需要从(一组)用户隐藏一些列/行,您将为它们实现一个视图。然后,您将在基表上拒绝SELECT。视图定义仅引用您希望在视图上授予SELECT的用户组可访问的那些列。

正如我所说,一旦您通过视图进行访问,就可以实现更复杂的要求,例如行级安全性。

(你可以在你的观点中做一些丑陋的事情,如果你已经开始动态更改隐私设置,但我不推荐它):

create table dbo.T1 (
    ID int not null,
    Col1 varchar(10) not null,
    Col2 varchar(10) not null,
    Col3 varchar(10) not null
)
go
create table dbo.Privacy (
    Schemaname sysname not null,
    Tablename sysname not null,
    Columnname sysname not null,
    Hidden bit not null
)
go
insert into dbo.T1 (ID,Col1,Col2,Col3)
select 1,'abc','def','ghi' union all
select 2,'ZYX','WVU','TSR'
go
insert into dbo.Privacy (Schemaname,Tablename,Columnname,Hidden)
select 'dbo','T1','Col2',1
go
create function dbo.ShowColumn (
    @Schema sysname,
    @Table sysname,
    @Column sysname
)
returns int
as
begin
    if exists(select * from dbo.Privacy where Schemaname = @Schema and Tablename = @Table and Columnname = @Column and Hidden=1)
    begin
        return 0
    end
    return 1
end
go
create view dbo.Virtual_T1 (ID,Col1,Col2,Col3)
as
    select
        ID,
        CASE WHEN 1 = dbo.ShowColumn('dbo','T1','Col1') THEN Col1 ELSE '' END,
        CASE WHEN 1 = dbo.ShowColumn('dbo','T1','Col2') THEN Col2 ELSE '' END,
        CASE WHEN 1 = dbo.ShowColumn('dbo','T1','Col3') THEN Col3 ELSE '' END
    from
        dbo.T1
go
select * from dbo.Virtual_T1

结果:

ID  Col1    Col2    Col3
1    abc             ghi
2    ZYX             TSR