首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >select时字符掩码输出数据

select时字符掩码输出数据
EN

Stack Overflow用户
提问于 2012-12-13 05:22:12
回答 7查看 48.5K关注 0票数 10

我使用的是SQL Server 2008。

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

这是我在执行select操作时从表中的列中获得的数据:

代码语言:javascript
运行
复制
column1

384844033434

743423547878

111224678885

我想要这样的输出:

代码语言:javascript
运行
复制
column1

384xxxxxx434

743xxxxxx878

111xxxxxx885

我该怎么做呢?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2012-12-13 05:45:13

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

您的视图将如下所示

代码语言:javascript
运行
复制
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触发器来更新基表。

票数 9
EN

Stack Overflow用户

发布于 2012-12-13 06:01:39

如果您知道您的数据字段将有多长,那么您可以使用另一个答案将生成的静态版本,但您始终可以创建一个函数来生成以下内容:

代码语言:javascript
运行
复制
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

对于此函数,您将传入要屏蔽的值。因此,您的查询将是:

代码语言:javascript
运行
复制
declare @temp table
(
    col1 varchar(50)
)

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

select dbo.MixUpCharacters(col1) col1
from @temp

请参阅SQL Fiddle with Demo

结果将是:

代码语言:javascript
运行
复制
|         COL1 |
----------------
| 384XXXXXX434 |
| 743XXXXXX878 |
| 111XXXXXX885 |

或者这里有一种使用递归CTE的方法:

代码语言:javascript
运行
复制
;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

票数 2
EN

Stack Overflow用户

发布于 2012-12-13 05:40:15

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

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

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13848872

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档