T-SQL :: information_type 未在 SQL Server 2019 中解析
T-SQL :: information_type is not parsed in SQL Server 2019
我的查询似乎没有解析 information_type
STEP TO REPRODUCE:
- 采用 AdventureWork 或任何其他测试数据库
- 右键点击你的测试数据库>
Tasks > Data Discovery and Classification > Classify Data...
然后对一堆数据进行分类
- 现在使用此查询来检查您的
information_type
列(这里我使用的是 AdventureWork2019):
粘贴此select并执行
SELECT
schema_name(O.schema_id) AS schema_name,
O.NAME AS table_name,
C.NAME AS column_name,
[Type] =
CASE
WHEN ct.[name] IN ('varchar', 'char') THEN ct.[name] + '(' + IIF(c.max_length = -1, 'max', CAST(c.max_length AS VARCHAR(25))) + ')'
WHEN ct.[name] IN ('nvarchar','nchar') THEN ct.[name] + '(' + IIF(c.max_length = -1, 'max', CAST(c.max_length / 2 AS VARCHAR(25)))+ ')'
WHEN ct.[name] IN ('decimal', 'numeric') THEN ct.[name] + '(' + CAST(c.precision AS VARCHAR(25)) + ', ' + CAST(c.scale AS VARCHAR(25)) + ')'
WHEN ct.[name] IN ('datetime2') THEN ct.[name] + '(' + CAST(c.scale AS VARCHAR(25)) + ')'
ELSE ct.[name]
END,
information_type,
label,
rank,
rank_desc,
CAST(
CASE
WHEN information_type = 'Contact Info'
THEN 'contact info'
ELSE 'not contact info'
END AS varchar(max)) as Checking_Content
FROM sys.sensitivity_classifications sc
JOIN sys.objects O
ON sc.major_id = O.object_id
JOIN sys.columns C
ON sc.major_id = C.object_id AND sc.minor_id = C.column_id
JOIN sys.types ct ON C.user_type_id = ct.user_type_id
--AND EP.minor_id = C.column_id
order by information_type
如您所见,即使列 information_type
的值为 Contact Info
,查询也会返回 not contact info
schema_name
table_name
column_name
Type
information_type
label
rank
rank_desc
Checking_Content
Person
PersonPhone
PhoneNumber
Phone
Contact Info
Confidential
20
MEDIUM
not contact info
Person
PersonPhone
PhoneNumberTypeID
int
Contact Info
Confidential
20
MEDIUM
not contact info
Person
PhoneNumberType
PhoneNumberTypeID
int
Contact Info
Confidential
20
MEDIUM
not contact info
Person
Address
AddressLine1
nvarchar(60)
Contact Info
Confidential
20
MEDIUM
not contact info
Person
Address
AddressLine2
nvarchar(60)
Contact Info
Confidential
20
MEDIUM
not contact info
Person
Address
City
nvarchar(30)
Contact Info
Confidential
20
MEDIUM
not contact info
Person
Address
PostalCode
nvarchar(15)
Contact Info
Confidential
20
MEDIUM
not contact info
Production
ProductReview
EmailAddress
nvarchar(50)
Contact Info
Confidential
20
MEDIUM
not contact info
Person
EmailAddress
EmailAddress
nvarchar(50)
Contact Info
Confidential
20
MEDIUM
not contact info
dbo
ErrorLog
UserName
sysname
Credentials
Confidential
20
MEDIUM
not contact info
Person
Password
PasswordHash
varchar(128)
Credentials
Confidential
20
MEDIUM
not contact info
Person
Password
PasswordSalt
varchar(10)
Credentials
Confidential
20
MEDIUM
not contact info
Sales
CreditCard
CreditCardID
int
Credit Card
Confidential
20
MEDIUM
not contact info
Sales
CreditCard
CardType
nvarchar(50)
Credit Card
Confidential
20
MEDIUM
not contact info
Sales
CreditCard
CardNumber
nvarchar(25)
Credit Card
Confidential
20
MEDIUM
not contact info
Sales
CreditCard
ExpYear
smallint
Credit Card
Confidential
20
MEDIUM
not contact info
Sales
PersonCreditCard
CreditCardID
int
Credit Card
Confidential
20
MEDIUM
not contact info
Sales
SalesOrderHeader
CreditCardID
int
Credit Card
Confidential
20
MEDIUM
not contact info
Sales
SalesOrderHeader
CreditCardApprovalCode
varchar(15)
Credit Card
Confidential
20
MEDIUM
not contact info
HumanResources
Employee
BirthDate
date
Date Of Birth
Confidential - GDPR
20
MEDIUM
not contact info
我很困惑:
你怎么看?
根据
exec sp_describe_first_result_set N'select * from sys.sensitivity_classifications sc'
information_type 是一个 sql_variant。这不符合 docs 但不应该成为问题,因为兼容类型已转换为 sql_variant 以进行比较而不会出现问题。乙
select case when cast(N'Contact Info' as sql_variant) = 'Contact Info' then 1 else 0 end
returns
1
所以这可能是一个错误。您可以通过显式转换为 nvarchar 来变通。例如
SELECT
schema_name(O.schema_id) AS schema_name,
O.NAME AS table_name,
C.NAME AS column_name,
[Type] =
CASE
WHEN ct.[name] IN ('varchar', 'char') THEN ct.[name] + '(' + IIF(c.max_length = -1, 'max', CAST(c.max_length AS VARCHAR(25))) + ')'
WHEN ct.[name] IN ('nvarchar','nchar') THEN ct.[name] + '(' + IIF(c.max_length = -1, 'max', CAST(c.max_length / 2 AS VARCHAR(25)))+ ')'
WHEN ct.[name] IN ('decimal', 'numeric') THEN ct.[name] + '(' + CAST(c.precision AS VARCHAR(25)) + ', ' + CAST(c.scale AS VARCHAR(25)) + ')'
WHEN ct.[name] IN ('datetime2') THEN ct.[name] + '(' + CAST(c.scale AS VARCHAR(25)) + ')'
ELSE ct.[name]
END,
information_type,
label,
rank,
rank_desc,
CAST(
CASE
WHEN cast(information_type as nvarchar(200)) = 'Contact Info'
THEN 'contact info'
ELSE 'not contact info'
END AS varchar(max)) as Checking_Content
FROM sys.sensitivity_classifications sc
JOIN sys.objects O
ON sc.major_id = O.object_id
JOIN sys.columns C
ON sc.major_id = C.object_id AND sc.minor_id = C.column_id
JOIN sys.types ct ON C.user_type_id = ct.user_type_id
--AND EP.minor_id = C.column_id
order by information_type
我的查询似乎没有解析 information_type
STEP TO REPRODUCE:
- 采用 AdventureWork 或任何其他测试数据库
- 右键点击你的测试数据库>
Tasks > Data Discovery and Classification > Classify Data...
然后对一堆数据进行分类 - 现在使用此查询来检查您的
information_type
列(这里我使用的是 AdventureWork2019):
粘贴此select并执行
SELECT
schema_name(O.schema_id) AS schema_name,
O.NAME AS table_name,
C.NAME AS column_name,
[Type] =
CASE
WHEN ct.[name] IN ('varchar', 'char') THEN ct.[name] + '(' + IIF(c.max_length = -1, 'max', CAST(c.max_length AS VARCHAR(25))) + ')'
WHEN ct.[name] IN ('nvarchar','nchar') THEN ct.[name] + '(' + IIF(c.max_length = -1, 'max', CAST(c.max_length / 2 AS VARCHAR(25)))+ ')'
WHEN ct.[name] IN ('decimal', 'numeric') THEN ct.[name] + '(' + CAST(c.precision AS VARCHAR(25)) + ', ' + CAST(c.scale AS VARCHAR(25)) + ')'
WHEN ct.[name] IN ('datetime2') THEN ct.[name] + '(' + CAST(c.scale AS VARCHAR(25)) + ')'
ELSE ct.[name]
END,
information_type,
label,
rank,
rank_desc,
CAST(
CASE
WHEN information_type = 'Contact Info'
THEN 'contact info'
ELSE 'not contact info'
END AS varchar(max)) as Checking_Content
FROM sys.sensitivity_classifications sc
JOIN sys.objects O
ON sc.major_id = O.object_id
JOIN sys.columns C
ON sc.major_id = C.object_id AND sc.minor_id = C.column_id
JOIN sys.types ct ON C.user_type_id = ct.user_type_id
--AND EP.minor_id = C.column_id
order by information_type
如您所见,即使列 information_type
的值为 Contact Info
not contact info
schema_name | table_name | column_name | Type | information_type | label | rank | rank_desc | Checking_Content |
---|---|---|---|---|---|---|---|---|
Person | PersonPhone | PhoneNumber | Phone | Contact Info | Confidential | 20 | MEDIUM | not contact info |
Person | PersonPhone | PhoneNumberTypeID | int | Contact Info | Confidential | 20 | MEDIUM | not contact info |
Person | PhoneNumberType | PhoneNumberTypeID | int | Contact Info | Confidential | 20 | MEDIUM | not contact info |
Person | Address | AddressLine1 | nvarchar(60) | Contact Info | Confidential | 20 | MEDIUM | not contact info |
Person | Address | AddressLine2 | nvarchar(60) | Contact Info | Confidential | 20 | MEDIUM | not contact info |
Person | Address | City | nvarchar(30) | Contact Info | Confidential | 20 | MEDIUM | not contact info |
Person | Address | PostalCode | nvarchar(15) | Contact Info | Confidential | 20 | MEDIUM | not contact info |
Production | ProductReview | EmailAddress | nvarchar(50) | Contact Info | Confidential | 20 | MEDIUM | not contact info |
Person | EmailAddress | EmailAddress | nvarchar(50) | Contact Info | Confidential | 20 | MEDIUM | not contact info |
dbo | ErrorLog | UserName | sysname | Credentials | Confidential | 20 | MEDIUM | not contact info |
Person | Password | PasswordHash | varchar(128) | Credentials | Confidential | 20 | MEDIUM | not contact info |
Person | Password | PasswordSalt | varchar(10) | Credentials | Confidential | 20 | MEDIUM | not contact info |
Sales | CreditCard | CreditCardID | int | Credit Card | Confidential | 20 | MEDIUM | not contact info |
Sales | CreditCard | CardType | nvarchar(50) | Credit Card | Confidential | 20 | MEDIUM | not contact info |
Sales | CreditCard | CardNumber | nvarchar(25) | Credit Card | Confidential | 20 | MEDIUM | not contact info |
Sales | CreditCard | ExpYear | smallint | Credit Card | Confidential | 20 | MEDIUM | not contact info |
Sales | PersonCreditCard | CreditCardID | int | Credit Card | Confidential | 20 | MEDIUM | not contact info |
Sales | SalesOrderHeader | CreditCardID | int | Credit Card | Confidential | 20 | MEDIUM | not contact info |
Sales | SalesOrderHeader | CreditCardApprovalCode | varchar(15) | Credit Card | Confidential | 20 | MEDIUM | not contact info |
HumanResources | Employee | BirthDate | date | Date Of Birth | Confidential - GDPR | 20 | MEDIUM | not contact info |
我很困惑:
你怎么看?
根据
exec sp_describe_first_result_set N'select * from sys.sensitivity_classifications sc'
information_type 是一个 sql_variant。这不符合 docs 但不应该成为问题,因为兼容类型已转换为 sql_variant 以进行比较而不会出现问题。乙
select case when cast(N'Contact Info' as sql_variant) = 'Contact Info' then 1 else 0 end
returns
1
所以这可能是一个错误。您可以通过显式转换为 nvarchar 来变通。例如
SELECT
schema_name(O.schema_id) AS schema_name,
O.NAME AS table_name,
C.NAME AS column_name,
[Type] =
CASE
WHEN ct.[name] IN ('varchar', 'char') THEN ct.[name] + '(' + IIF(c.max_length = -1, 'max', CAST(c.max_length AS VARCHAR(25))) + ')'
WHEN ct.[name] IN ('nvarchar','nchar') THEN ct.[name] + '(' + IIF(c.max_length = -1, 'max', CAST(c.max_length / 2 AS VARCHAR(25)))+ ')'
WHEN ct.[name] IN ('decimal', 'numeric') THEN ct.[name] + '(' + CAST(c.precision AS VARCHAR(25)) + ', ' + CAST(c.scale AS VARCHAR(25)) + ')'
WHEN ct.[name] IN ('datetime2') THEN ct.[name] + '(' + CAST(c.scale AS VARCHAR(25)) + ')'
ELSE ct.[name]
END,
information_type,
label,
rank,
rank_desc,
CAST(
CASE
WHEN cast(information_type as nvarchar(200)) = 'Contact Info'
THEN 'contact info'
ELSE 'not contact info'
END AS varchar(max)) as Checking_Content
FROM sys.sensitivity_classifications sc
JOIN sys.objects O
ON sc.major_id = O.object_id
JOIN sys.columns C
ON sc.major_id = C.object_id AND sc.minor_id = C.column_id
JOIN sys.types ct ON C.user_type_id = ct.user_type_id
--AND EP.minor_id = C.column_id
order by information_type