2012-12-12 47 views
7

我正在使用SQL Server 2008.选择字符掩码输出数据

我想字符掩码查询的输出数据。

这是从上表中的列我的数据做一个选择时:

column1 

384844033434 

743423547878 

111224678885 

我想这样的输出:

column1 

384xxxxxx434 

743xxxxxx878 

111xxxxxx885 

我怎样才能做到这一点?

+2

外貌就像你在谈论[人物掩饰](http://www.simple-talk。com/sql/database-administration/obfuscating-your-sql-server-data /)而不是加密 –

+0

yea是字符掩码 – pyram

回答

7

您将不得不使用一个视图,并拒绝所有用户对基础表的SELECT访问。

你的观点会看起来像

SELECT 
    SUBSTRING(x.SecurityNumber,1,3) + 
    'xxxxx' + 
    SUBSTRING(x.SecurityNumber,LEN(x.SecurityNumber) - 2, LEN(x.SecurityNumber)) 
    AS column1 
FROM underlyingTable x 

然后,您可以选择访问给予你的用户只是这一观点,并在您所描述的方式掩盖了出来。

如果您希望您的客户端软件能够插入或更新此表中的数据,则可以使用INSTEAD OF INSERT或INSTEAD OF UPDATE触发器来更新基表。

+0

谢谢大家,谢谢大家的回复! – pyram

+0

我正在使用SQL Server 2008的sqlcmd,发现偏移量不同。为了正确输出,我使用了'SUBSTRING(x.SecurityNumber,1,3)+'xxxxx'+ SUBSTRING(x.SecurityNumber,LEN(x.SecurityNumber) - 2,LEN(x.SecurityNumber))' – David

+0

Thanks @David。据此编辑。 –

1

一个简单的select查询只会返回它在表上的内容,不管它是否被加密。

所以,我认为你不能在数据库级别上做到这一点。

为了您的要求,您将需要一个双向加密算法在应用程序中使用,这样你就可以将其保存加密的数据库之前对数据进行加密,并从数据库中获取的信息进行加密和解密在你applicaition。

2

如果你知道你的数据的字段多久会,那么你可以使用对方的回答会产生静态版本,但你总是可以创建一个函数来产生这样的:

CREATE FUNCTION MixUpCharacters 
(
    @OrigVal varchar(max) 
) 
RETURNS varchar(max) 
AS 
BEGIN 

DECLARE @NewVal varchar(max) 
DECLARE @OrigLen int 
DECLARE @LoopCt int 
DECLARE @Part varchar(max) = '' 
Declare @PartLength int 

SET @NewVal = '' 
SET @OrigLen = DATALENGTH(@OrigVal) 
SET @LoopCt = 1 

SET @Part = SUBSTRING(@OrigVal, 4, len(@OrigVal)-6) 
set @PartLength = LEN(@Part) 

WHILE @LoopCt <= @PartLength 
    BEGIN 
     -- Current length of possible characters 
     SET @NewVal = @NewVal + 'X' 

     -- Advance the loop 
     SET @LoopCt = @LoopCt + 1 
    END 

    Return REPLACE(@OrigVal, @Part, @NewVal) 
END 

对于本函数,您将传入要屏蔽的值。所以,你的查询是:

declare @temp table 
(
    col1 varchar(50) 
) 

insert into @temp 
values ('384844033434'), ('743423547878'), ('111224678885') 

select dbo.MixUpCharacters(col1) col1 
from @temp 

SQL Fiddle with Demo

其结果将是:

|   COL1 | 
---------------- 
| 384XXXXXX434 | 
| 743XXXXXX878 | 
| 111XXXXXX885 | 

或者在这里是一种递归CTE做到这一点:

;with data(col1) as 
(
    select '384844033434' 
    union all 
    select '7434235878' 
    union all 
    select '111224678885' 
), 
s1 (col1, repfull) as 
(
    select col1, 
     SUBSTRING(col1, 4, len(col1)-6) repfull 
    from data 
), 
s2 (col1, item, repfull, r) as 
(
    select col1, 
     cast('x' as varchar(max)), 
     right(repfull, LEN(repfull)-1), 
     repfull 
    from s1 
    union all 
    select col1, 
     'x'+ cast(item as varchar(max)), 
     right(repfull, LEN(repfull)-1), 
     r 
    from s2 
    where len(repfull) >0 
) 
select REPLACE(col1, r, item) newValue 
from 
(
    select col1, item, R, 
     ROW_NUMBER() over(partition by col1 order by len(item) desc) rn 
    from s2 
) src 
where rn = 1 

SQL Fiddle with Demo

1

很简单兄弟

SELECT CONCAT (SUBSTR('Your string',1,3),LPAD(SUBSTR('Your string',-3),LENGTH('Your string')-1,'*')) RESULT FROM dual 

输出:

您*******荷兰国际集团

如果是num类型转换为char

1

如果你想掩盖你不知道场地长度的场地。您可以升级bluefeet的这样的代码:

ALTER FUNCTION MixUpCharacters 
(
    @OrigVal varchar(MAX) 
) 
RETURNS varchar(MAX) 
AS 
BEGIN 

DECLARE @NewVal NVARCHAR(MAX) 
DECLARE @OrigLen INT 
DECLARE @LoopCt INT 
DECLARE @Part NVARCHAR(MAX) = '' 
DECLARE @PartLength INT  -- MastLength 
DECLARE @PartStartIndex INT -- MaskStartIndex 

SET @NewVal = '' 
SET @LoopCt = 1 
SET @OrigLen = LEN(@OrigVal) 

IF(@OrigLen = 1) 
    BEGIN 
     RETURN 'X' 
    END 
IF(@OrigLen < 6) 
    BEGIN 
     SET @PartStartIndex = @OrigLen/2 
     SET @PartLength = @OrigLen - @PartStartIndex 
     SET @Part = SUBSTRING(@OrigVal, @PartStartIndex, @PartLength) 
    END 
ELSE IF(@OrigLen < 8) 
    BEGIN 
     SET @PartStartIndex = 3 
     SET @PartLength = @OrigLen - @PartStartIndex - 1 
     SET @Part = SUBSTRING(@OrigVal, @PartStartIndex, @PartLength) 
    END 
ELSE 
    BEGIN 
     SET @PartStartIndex = 4 
     SET @PartLength = @OrigLen - @PartStartIndex - 2 
     SET @Part = SUBSTRING(@OrigVal, @PartStartIndex, @PartLength) 
    END 

WHILE @LoopCt <= @PartLength 
    BEGIN 
     -- Current length of possible characters 
     SET @NewVal = @NewVal + 'X' 

     -- Advance the loop 
     SET @LoopCt = @LoopCt + 1 
    END 

    RETURN REPLACE(@OrigVal, @Part, @NewVal) 
END 

您可以测试这样的:

SELECT dbo.MixUpCharacters('1') 
UNION ALL 
SELECT dbo.MixUpCharacters('12') 
UNION ALL 
SELECT dbo.MixUpCharacters('123') 
UNION ALL 
SELECT dbo.MixUpCharacters('1234') 
UNION ALL 
SELECT dbo.MixUpCharacters('12345') 
UNION ALL 
SELECT dbo.MixUpCharacters('123456') 
UNION ALL 
SELECT dbo.MixUpCharacters('1234567') 
UNION ALL 
SELECT dbo.MixUpCharacters('12345678') 
UNION ALL 
SELECT dbo.MixUpCharacters('123456789') 
UNION ALL 
select dbo.MixUpCharacters('1234567890') 
UNION ALL 
select dbo.MixUpCharacters('12345678910') 

结果:

X 
X2 
XX3 
1XX4 
1XXX5 
12XX56 
12XXX67 
123XX678 
123XXX789 
123XXXX890 
123XXXXX910 
0

SQL Server 2016+你可以使用Dynamic Data Masking功能。

动态数据屏蔽通过将敏感数据屏蔽给非特权用户来限制敏感数据的暴露。动态数据屏蔽有助于防止未经授权访问敏感数据,因为客户可以指定要显示多少敏感数据,同时对应用程序层的影响最小。这是一项数据保护功能,可将敏感数据隐藏在指定数据库字段的查询结果集中,而数据库中的数据不会更改。动态数据屏蔽易于与现有应用程序一起使用,因为屏蔽规则应用于查询结果中。 许多应用程序可以屏蔽敏感数据而无需修改现有查询。

CREATE TABLE #tab(ID INT IDENTITY(1,1), column1 VARCHAR(12)); 

INSERT INTO #tab(column1) 
VALUES('384844033434'),('743423547878'),('111224678885'); 

SELECT * FROM #tab; 

输出:

╔════╦══════════════╗ 
║ ID ║ column1 ║ 
╠════╬══════════════╣ 
║ 1 ║ 384844033434 ║ 
║ 2 ║ 743423547878 ║ 
║ 3 ║ 111224678885 ║ 
╚════╩══════════════╝ 

ALTER TABLE #tab 
ALTER COLUMN column1 VARCHAR(12) MASKED WITH (FUNCTION = 'partial(3,"xxxxxx",3)'); 

SELECT * FROM #tab; 

输出:

╔════╦══════════════╗ 
║ ID ║ column1 ║ 
╠════╬══════════════╣ 
║ 1 ║ 384xxxxxx434 ║ 
║ 2 ║ 743xxxxxx878 ║ 
║ 3 ║ 111xxxxxx885 ║ 
╚════╩══════════════╝ 

LiveDemo