T-SQL :: 列出所有表、列和透视内容
Posted
技术标签:
【中文标题】T-SQL :: 列出所有表、列和透视内容【英文标题】:T-SQL :: List all tables, columns and pivot content 【发布时间】:2021-12-28 13:40:33 【问题描述】:我正在使用 SSMS 工具 Data Discovery and Classification。
该工具会自动搜索列名称,如%address%
、%name%
、%surname%
、%e-mail%
、%tax%
、%zip%
等...
并且很好地向您建议它可能是一个明智的数据。
事实上,在盎格鲁-撒克逊社会之外,列名不是英文的,但可以是法文、西班牙文、意大利文等。
所以我找到了一个查询,可以帮助我根据我的语言列出合理的数据:
SELECT schema_name(tab.schema_id) AS schema_name
,tab.name AS table_name
,col.name AS column_name
,t.name AS data_type
,NULL as Data_Preview
FROM sys.tables AS tab
INNER JOIN sys.columns AS col ON tab.object_id = col.object_id
LEFT JOIN sys.types AS t ON col.user_type_id = t.user_type_id
ORDER BY schema_name
,table_name
,column_id;
非常好。
但如果我可以添加一个名为 Content
的最后一列会更好
你能帮我存档吗?
这将是一个 DYO 数据发现和分类。
编辑:我可能表达得很糟糕。
我正在针对 AdventureWorks2019 运行 mz 查询:
schema_name | table_name | column_name | data_type | Data_Preview |
---|---|---|---|---|
Person | Address | AddressID | int | NULL |
Person | Address | AddressLine1 | nvarchar | NULL |
Person | Address | AddressLine2 | nvarchar | NULL |
Person | Address | City | nvarchar | NULL |
Person | Address | StateProvinceID | int | NULL |
Person | Address | PostalCode | nvarchar | NULL |
我想PIVOT
每一列的内容(比如说TOP 5
)到最后一列
schema_name | table_name | column_name | data_type | Data_Preview |
---|---|---|---|---|
Person | Address | AddressID | int | 1,2,3,4,5 |
Person | Address | AddressLine1 | nvarchar | 1970 Napa Ct.,9833 Mt. Dias Blv.,7484 Roundtree Drive,9539 Glenside Dr,1226 Shoe St. |
Person | Address | AddressLine2 | nvarchar | NULL,NULL,NULL,NULL,NULL |
Person | Address | City | nvarchar | Bothell,Bothell,Bothell,Bothell,Bothell |
Person | Address | StateProvinceID | int | 79,79,79,79,79 |
Person | Address | PostalCode | nvarchar | 98011,98011,98011,98011,98011 |
每个数据可以用逗号或其他分隔。结果是我想预览列中实际存在的数据:
这家伙显然是来存档的:
https://docs.microsoft.com/en-us/answers/questions/285445/how-to-get-column-values-in-one-comma-separated-va.html Pivot and comma Separated value https://www.mikekale.com/rows-to-comma-separated-lists-in-sql-server/谢谢
【问题讨论】:
如果您可以提供一个包含几行示例数据的示例表以及基于您的示例数据的所需输出,那么这里真正有帮助的地方。 嗨@SeanLange,我更新了我的问题。谢谢 您将不得不为此使用动态 sql。我没有仔细查看 Nav 发布的解决方案,但这似乎是您所需要的。 仅供参考,该工具正在寻找敏感数据,而不是敏感数据。如果您的数据库中的数据是合理的,我怀疑该工具是否有任何想法。检测敏感数据(或者可能是非敏感数据)的工具可能会检查您的列是否具有正确的数据类型,例如将电话号码存储在varchar
中或将日期存储在int
中;两者都不明智。
另外,赏金描述是错误的,STUFF
除了将字符串的一部分替换为另一部分之外,没有做任何事情。 “魔术”由FOR XML PATH
完成;所有STUFF
在此类解决方案中所做的就是删除第一个分隔符。
【参考方案1】:
已更新以支持 2016
DROP TABLE IF EXISTS #ColumnsToDisplay
SELECT ROW_NUMBER () OVER (ORDER BY tab.name) AS Iteration,
s.name AS SchemaName,
tab.name AS table_name,
col.column_id,
col.name AS column_name,
t.name AS data_type,
col.max_length,
col.precision AS PrecisionNumber,
CAST(NULL AS VARCHAR(MAX)) AS DataSample
INTO #ColumnsToDisplay
FROM sys.tables AS tab
JOIN sys.schemas AS s
ON s.schema_id = tab.schema_id
JOIN sys.columns AS col
ON col.object_id = tab.object_id
LEFT JOIN sys.types AS t
ON col.user_type_id = t.user_type_id
DECLARE @Iterations INT = 0,
@CurrentIteration INT = 1;
SELECT @Iterations = MAX (Iteration)
FROM #ColumnsToDisplay
WHILE @CurrentIteration <= @Iterations
BEGIN
DECLARE @CurrentTableName VARCHAR(100) = '',
@CurrentColumnName VARCHAR(100) = '',
@DynamicQuery NVARCHAR(1000) = N''
DECLARE @Sample VARCHAR(MAX)
SET @CurrentTableName = '';
SET @DynamicQuery = N'';
SELECT @CurrentTableName = CONCAT (ttq.SchemaName, '.', ttq.table_name),
@CurrentColumnName = ttq.column_name
FROM #ColumnsToDisplay AS ttq
WHERE ttq.Iteration = @CurrentIteration
IF (@CurrentTableName = '')
BEGIN
SET @CurrentIteration += 1
CONTINUE
END
-- SQL Server 2019
-- SET @DynamicQuery = CONCAT (N'
-- SELECT @Sample = STRING_AGG(t.ColumnData,'', '')
-- FROM (
-- SELECT TOP 5 CAST(x.[', @CurrentColumnName, '] AS VARCHAR(MAX)) AS ColumnData
-- FROM ', @CurrentTableName, ' AS x
-- WHERE x.[', @CurrentColumnName, '] IS NOT NULL
-- )t')
-- SQL Server 2016 and lower where Stuff is supported
SET @DynamicQuery = CONCAT (N'
SELECT @Sample = STUFF((SELECT '', ''+ t.ColumnData
FROM (
SELECT TOP 5 CAST(x.[', @CurrentColumnName, '] AS VARCHAR(MAX)) AS ColumnData
FROM ', @CurrentTableName, ' AS x
WHERE x.[', @CurrentColumnName, '] IS NOT NULL
) AS t
FOR XML PATH('''')),1,1,'''')')
EXECUTE sys.sp_executesql @DynamicQuery,
N'@Sample VARCHAR(MAX) OUTPUT',
@Sample = @Sample OUTPUT
UPDATE #ColumnsToDisplay
SET DataSample = @Sample
WHERE Iteration = @CurrentIteration
SET @CurrentIteration += 1
END
SELECT ctd.Iteration,
ctd.SchemaName,
ctd.table_name,
ctd.column_id,
ctd.column_name,
ctd.data_type,
ctd.max_length,
ctd.PrecisionNumber,
ctd.DataSample
FROM #ColumnsToDisplay AS ctd
【讨论】:
谢谢@Nav,但我需要的更容易。我表达得很糟糕。我现在更新了我的问题。谢谢 您的代码已完成,但我可以在哪里选择结果? 我尝试修改您的代码以使其可用于 SQL Server 2016 以下示例:docs.microsoft.com/en-us/answers/questions/285445/…。 ` SET @DynamicQuery = CONCAT (N' SELECT @Sample = STUFF((SELECT t.ColumnData,'', '' FROM (SELECT TOP 5 CAST(x.', @CurrentColumnName, ' AS VARCHAR(MAX)) AS ColumnData FROM ', @CurrentTableName, 'AS x WHERE x.', @CurrentColumnName, ' IS NOT NULL FOR XML PATH('') ), 1, 1, ''))t')` 更新了查询以支持 sql server 2016 @Nav,使用QUOTENAME
而不是连接括号来包围列。这将处理标识符中的括号。以上是关于T-SQL :: 列出所有表、列和透视内容的主要内容,如果未能解决你的问题,请参考以下文章