【问题标题】:Mask values in a SQL Query string for SQL ServerSQL Server 的 SQL 查询字符串中的掩码值
【发布时间】:2022-08-19 05:08:16
【问题描述】:

我是一名 SQL Server DBA。我想编写一个程序,可以提供给我的团队的其他成员,他们可以在其中查看服务器上当前正在运行的查询的文本(类似于我们在 sp_who2 中查看的方式),但所有值都被屏蔽了。 例子:

Query text Query text after Masking
Select * from sometable where rating = \'4\' Select * from sometable where rating = \'****\'
Select name, id from sometable where id = \'3233\' Select name, id from sometable where id = \'****\'
UPDATE Customers SET ContactName = \'Alfred Schmidt\' WHERE CustomerID = 1; UPDATE Customers SET ContactName = \'****\' WHERE CustomerID = ****;
INSERT INTO Customers (CustomerName, ContactName) VALUES (\'Cardinal\', \'Tom B. Erichsen\'); INSERT INTO Customers (CustomerName, ContactName) VALUES (\'*****\', \'****\');
  • 使用常规 SQL Server 代码很难做到这一点。如果您的存储过程可以访问正则表达式替换功能,则将\'.*?\' 替换为\'****\'
  • @TimBiegeleisen 是的。这是一个很好的建议。像第三个例子一样处理整数有什么建议吗?
  • 正则表达式是否适合您?
  • 实际上似乎我没有它,但我认为在 sql 中编写正则表达式替换方法可能不会太难......
  • 在没有参数值的情况下,做任何有用的事情(例如性能调整)都会受到打击。实际的最终目标是什么?你有 XY 问题吗?

标签: sql sql-server data-masking pii


【解决方案1】:

如果我正确理解您的问题。 您可以使用此查询:

select 
    r.session_id,
    r.status,
    r.command,
    r.cpu_time,
    r.total_elapsed_time,
    t.text
from sys.dm_exec_requests as r
cross apply sys.dm_exec_sql_text(r.sql_handle) as t

例如 我现在在我的 SQL 服务器上运行它:

(@P1 nvarchar(5),@P2 bigint,@P3 int,@P4 numeric(28, 12),@P5 nvarchar(5),@P6 datetime,@P7 datetime)
SELECT SUM(A.SETTLEAMOUNTCUR) FROM CUSTSETTLEMENT A,CUSTTRANS B WHERE ((A.DATAAREAID=@P1) AND (((A.TRANSRECID=@P2) AND (A.CANBEREVERSED=@P3)) AND (A.SETTLEAMOUNTCUR<>@P4))) AND ((B.DATAAREAID=@P5) AND (((B.RECID=A.OFFSETRECID) AND (B.TRANSDATE>=@P6)) AND (B.TRANSDATE<=@P7)))

所有变量都是隐藏的。

【讨论】:

  • 您确定不是您的客户端应用程序将查询转换为该表单吗?当我将where r.session_id = 99 附加到您的查询并运行它时,我会按原样返回整个查询,即它在其中编码了99,而没有引入任何@P1
  • @DávidLaczkó 这是因为查询是参数化的,所有查询都应该如此。上面的输出是 XEvents 和 SQL Profiler 在这种情况下返回的内容。
  • @Charlieface但这是否意味着这不能成为OP查询的解决方案,这些查询显然没有参数化?编辑:我刚刚看到你在评论中问了这个。
【解决方案2】:

您可以尝试一些 XML 技巧来处理字符串。 首先将所有单引号替换为空标记&lt;X/&gt;,以获得如下所示的 XML。

INSERT INTO Customers (CustomerName, ContactName) 
  VALUES (<X />Cardinal<X />, <X />Tom B. Erichsen<X />);

然后你粉碎 xml 以获得文本节点和 mod 2 为 0 的节点号是你想要屏蔽的节点号。

之后,您可以使用掩码值重建查询字符串。

除了使用Translate 或嵌套替换从查询中删除所有数字之外,我还没有找到一种处理数字的方法,当然这也会从表名和列名中删除数字。

你可以试试这样的。

declare @S nvarchar(max);
declare @X xml;

set @S = N'UPDATE Customers SET ContactName = ''Alfred Schmidt'' WHERE CustomerID = 1;';

set @X = replace(@S, '''', '<X/>');

with C as
(
  select T.X.value('.', 'nvarchar(max)') as V, 
         row_number() over(order by T.X) as RN
  from @X.nodes('text()') as T(X)
)
select @S = (
            select case when C.RN % 2 = 0 then '''*****''' else C.V end
            from C
            order by C.RN
            for xml path(''), type
            ).value('text()[1]', 'nvarchar(max)');

set @S = translate(@S, '0123456789', '**********')

print @S;

结果:

UPDATE Customers SET ContactName = '*****' WHERE CustomerID = *;

注意:刚刚意识到此解决方案无法处理字符串值包含单引号的情况,但我认为这可能会激发更强大的解决方案,因此我将其留在这里。

【讨论】:

  • 我真的很喜欢这个解决方案 Mikael,这是我无法弄清楚表名中有数字的唯一情况。类似于表名是 mytable878 的东西现在更改为 mytable*** ..
【解决方案3】:

sys.sp_get_query_template

fiddle

declare @t nvarchar(max), @p nvarchar(max);
declare @q nvarchar(max) = 'UPDATE Customers SET ContactName = N''Alfred Schmidt'' WHERE CustomerID = 1 AND Rate = 0.75 AND Rver = 0x0102 AND DateCreated = dateadd(day, -10, ''202z0818'')';

exec sys.sp_get_query_template @querytext = @q, @templatetext = @t OUTPUT, @parameters = @p OUTPUT;

select p,
  case when tp like '%int' then cast('****' as nvarchar(40))
  when tp like 'decimal(%' or tp like 'numeric(%' then '**.**'
  when tp like '%binary(%' then '0x****'
  when tp like 'n%char%' then 'N''****'''
  else '''****'''
  end as rv
into #t
from
(
select *, '@'+left(s.value, charindex(' ', s.value+' ')-1) as p, stuff(s.value, 1, charindex(' ', s.value), '') as tp
from string_split(replace(@p, ',@', '@'), '@') as s
where s.value <> ''
) as ss;

update #t
set @t = replace(@t, p, rv);

select @q union all select @t;

【讨论】:

    猜你喜欢
    • 2011-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多