【发布时间】:2022-01-02 20:53:18
【问题描述】:
我正在尝试通过sys.objects 加入INFORMATION_SCHEMA.COLUMNS 和sys.masked_columns。
这是我的查询:
SELECT
TABLE_SCHEMA,
TABLE_NAME,
COLUMN_NAME,
DATA_TYPE
+ CASE WHEN DATA_TYPE IN ('char', 'nchar', 'varchar', 'nvarchar', 'binary', 'varbinary')
AND CHARACTER_MAXIMUM_LENGTH > 0
THEN COALESCE('(' + CONVERT(varchar, CHARACTER_MAXIMUM_LENGTH) + ')', '')
ELSE ''
END
+ CASE WHEN DATA_TYPE IN ('decimal', 'numeric')
THEN COALESCE('(' + CONVERT(varchar, NUMERIC_PRECISION) + ',' + CONVERT(varchar, NUMERIC_SCALE) + ')', '')
ELSE ''
END AS Declaration_Type,
--CASE WHEN IS_NULLABLE='NO' THEN 'NOT ' ELSE '' END + 'NULL' AS Nullable
m.is_masked,
m.masking_function
FROM
INFORMATION_SCHEMA.COLUMNS c
JOIN
sys.objects o ON c.table_name = o.name
JOIN
sys.masked_columns m ON o.[object_id] = m.[object_id]
ORDER BY
1, 2, 3
并返回:
| TABLE_SCHEMA | TABLE_NAME | COLUMN_NAME | Declaration_Type | is_masked | masking_function |
|---|---|---|---|---|---|
| Person | EmailAddress | BusinessEntityID | int | 1 | email() |
| Person | EmailAddress | EmailAddress | nvarchar(50) | 1 | email() |
| Person | EmailAddress | EmailAddressID | int | 1 | email() |
| Person | EmailAddress | ModifiedDate | datetime | 1 | email() |
| Person | EmailAddress | rowguid | uniqueidentifier | 1 | email() |
但是结果是错误的,因为它显示Person.EmailAddress中的所有列都被屏蔽了。
如果我检查这个查询:
SELECT c.name, tbl.name as table_name, c.is_masked, c.masking_function
FROM sys.masked_columns AS c
JOIN sys.tables AS tbl
ON c.[object_id] = tbl.[object_id]
WHERE is_masked = 1;
SSMS 仅返回 1 个屏蔽列:
| name | table_name | is_masked | masking_function | |
|---|---|---|---|---|
| EmailAddress | EmailAddress | 1 | email() |
为什么要返回Person.EmailAddress 中的每一列?
【问题讨论】:
-
显然它也应该加入 column_id 而不仅仅是对象 id。否则,您如何期望仅过滤被屏蔽的列? (虽然使用
sys.columns而不是INFORMATION_SCHEMA.COLUMNS因为这不会暴露 id -
将
INFORMATION_SCHEMA与系统视图混在一起让我变成了一只悲伤的熊猫。根本不要使用INFORMATION_SCHEMA,除非您的意图是编写(稍微)可移植的代码,这不是因为屏蔽不是标准功能;这些“标准”视图实际上只是作为一个兼容层存在,并且(至少在 SQL Server 上)不是一个很好的实现。 -
也意味着你不会遇到像
sys.objects o on c.table_name = o.name这样的错误连接条件,如果同一个命名表存在于多个模式中,这将是不正确的 -
明白了,谢谢@JeroenMostert 和 MartinSmith
标签: sql-server tsql join data-masking