12

我正在使用 SQL Server 2008。

我想对查询的输出数据进行字符屏蔽。

这是我在进行选择时来自表格列的数据:

column1

384844033434

743423547878

111224678885

我想要这样的输出:

column1

384xxxxxx434

743xxxxxx878

111xxxxxx885

我怎样才能做到这一点?

4

9 回答 9

10

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

您的视图看起来像

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

然后,您可以授予您的用户 SELECT 访问此视图的权限,并按照您描述的方式屏蔽输出。

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

于 2012-12-12T21:45:13.130 回答
5

SQL Server 2016+您可以使用动态数据屏蔽功能。

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

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

于 2016-05-05T16:46:26.887 回答
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

结果将是:

|         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

于 2012-12-12T22:01:39.327 回答
1

一个简单的选择查询将只返回它在表上的内容,无论它是否加密。

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

根据您的要求,您需要在应用程序中使用双向加密算法,因此您可以在将数据加密保存在数据库中之前对其进行加密,并从数据库中获取加密信息并在您的应用程序中对其进行解密。

于 2012-12-12T21:40:15.397 回答
1

很简单的兄弟

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

输出 :

你***

如果是num类型转换为char

于 2015-08-17T06:37:28.223 回答
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
于 2016-01-13T09:04:45.480 回答
0

这也适用于检索时屏蔽输出。

SELECT CONCAT(SUBSTRING(column1, 1, 3),'xxxxxx',SUBSTRING(column1, 10, 3)) FROM tableName;

如果值长度不固定,可以使用下面的。

SELECT CONCAT(SUBSTRING(column1, 1, 3),'xxxxxx',SUBSTRING(column1, LEN(column1)-2, 3)) FROM tableName;
于 2021-03-17T05:29:04.103 回答
0
concat('XXXXXXXXX',right(aadharno,4)) as aadharno

它将掩盖 aadhar 号码,从右数第四个。

于 2022-02-21T05:44:16.673 回答
0
concat('XXXXXXXXX',right(aadharno,4)) as aadharno

它将掩盖 aadhar 号码。
输出将如下所示: XXXXXXXXX7995

于 2022-02-21T06:26:25.083 回答