端口 STRING_AGG 到 FOR XML
Port STRING_AGG to FOR XML
我目前正在研究 Data Discovery and Classification and I have a ,它允许我在进行分类时查看数据预览。
这是它如何针对 AdventureWorks 工作的示例:
DECLARE @TableName VARCHAR(100) = 'Product'
DROP TABLE IF EXISTS #ColumnsToDisplay
SELECT ROW_NUMBER () OVER (ORDER BY tab.name) AS Iteration,
SCHEMA_NAME (tab.schema_id) AS schema_name,
tab.name AS table_name,
--col.column_id,
col.name AS column_name,
--t.name AS data_type,
--col.max_length,
--col.precision,
CAST(NULL AS VARCHAR(MAX)) AS DataSample
INTO #ColumnsToDisplay
FROM sys.tables AS tab
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
WHERE tab.name = @TableName
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.schema_name, '.', ttq.table_name),
@CurrentColumnName = ttq.column_name
FROM #ColumnsToDisplay AS ttq
WHERE ttq.Iteration = @CurrentIteration
IF (@CurrentTableName = '')
BEGIN
SET @CurrentIteration += 1
CONTINUE
END
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')
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.schema_name,
ctd.table_name,
--ctd.column_id,
ctd.column_name,
--ctd.data_type,
--ctd.max_length,
--ctd.precision,
ctd.DataSample
FROM #ColumnsToDisplay AS ctd
这里是结果:
Iteration
schema_name
table_name
column_name
DataSample
1
Production
Product
ProductID
980, 365, 771, 404, 977
2
Production
Product
Name
Adjustable Race, All-Purpose Bike Stand, AWC Logo Cap, BB Ball Bearing, Bearing Ball
3
Production
Product
ProductNumber
AR-5381, BA-8327, BB-7421, BB-8107, BB-9108
4
Production
Product
MakeFlag
0, 0, 1, 0, 1
5
Production
Product
FinishedGoodsFlag
0, 0, 0, 0, 0
6
Production
Product
Color
Black, Black, Black, Silver, Silver
问题是此查询仅适用于 SQL Server 2017 及更高版本,因为它使用 STRING_AGG
。对于 SQL Server 2016 及以下版本,我应该改用 STUFF
。
我遵循了这个 example 但我无法真正修复它。
我唯一知道的是我需要移植的代码部分是这样的:
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')
谁能帮我把 STRING_AGG
移植到 STUFF
?
谢谢
首先,让我们澄清一下,正如 Stu 提到的那样,stuff
只是用于删除第一个分隔符。
所以,如果你有
'a','b','c'
并且您想使用逗号分隔符,xml 路径会给您:
,a,b,c
然后你用东西来截断第一个逗号:
a,b,c
您的查询似乎根本没有分隔符,因此您不会使用 stuff
。考虑到这一点,这是我 未经测试 的猜测,在其之上添加动态查询是棘手的事情:
SET @DynamicQuery = CONCAT (N'
set @Sample =
(
select t.ColumnData
from ', @CurrentTableName, ' AS x
where x.', @CurrentColumnName, ' IS NOT NULL
for xml path(''''), type
).value(''.'',''nvarchar(max)'')
)t')
谢谢你的帮助。
正确的问题是:
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,'''')')
我目前正在研究 Data Discovery and Classification and I have a
这是它如何针对 AdventureWorks 工作的示例:
DECLARE @TableName VARCHAR(100) = 'Product'
DROP TABLE IF EXISTS #ColumnsToDisplay
SELECT ROW_NUMBER () OVER (ORDER BY tab.name) AS Iteration,
SCHEMA_NAME (tab.schema_id) AS schema_name,
tab.name AS table_name,
--col.column_id,
col.name AS column_name,
--t.name AS data_type,
--col.max_length,
--col.precision,
CAST(NULL AS VARCHAR(MAX)) AS DataSample
INTO #ColumnsToDisplay
FROM sys.tables AS tab
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
WHERE tab.name = @TableName
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.schema_name, '.', ttq.table_name),
@CurrentColumnName = ttq.column_name
FROM #ColumnsToDisplay AS ttq
WHERE ttq.Iteration = @CurrentIteration
IF (@CurrentTableName = '')
BEGIN
SET @CurrentIteration += 1
CONTINUE
END
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')
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.schema_name,
ctd.table_name,
--ctd.column_id,
ctd.column_name,
--ctd.data_type,
--ctd.max_length,
--ctd.precision,
ctd.DataSample
FROM #ColumnsToDisplay AS ctd
这里是结果:
Iteration | schema_name | table_name | column_name | DataSample |
---|---|---|---|---|
1 | Production | Product | ProductID | 980, 365, 771, 404, 977 |
2 | Production | Product | Name | Adjustable Race, All-Purpose Bike Stand, AWC Logo Cap, BB Ball Bearing, Bearing Ball |
3 | Production | Product | ProductNumber | AR-5381, BA-8327, BB-7421, BB-8107, BB-9108 |
4 | Production | Product | MakeFlag | 0, 0, 1, 0, 1 |
5 | Production | Product | FinishedGoodsFlag | 0, 0, 0, 0, 0 |
6 | Production | Product | Color | Black, Black, Black, Silver, Silver |
问题是此查询仅适用于 SQL Server 2017 及更高版本,因为它使用 STRING_AGG
。对于 SQL Server 2016 及以下版本,我应该改用 STUFF
。
我遵循了这个 example 但我无法真正修复它。
我唯一知道的是我需要移植的代码部分是这样的:
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')
谁能帮我把 STRING_AGG
移植到 STUFF
?
谢谢
首先,让我们澄清一下,正如 Stu 提到的那样,stuff
只是用于删除第一个分隔符。
所以,如果你有
'a','b','c'
并且您想使用逗号分隔符,xml 路径会给您:
,a,b,c
然后你用东西来截断第一个逗号:
a,b,c
您的查询似乎根本没有分隔符,因此您不会使用 stuff
。考虑到这一点,这是我 未经测试 的猜测,在其之上添加动态查询是棘手的事情:
SET @DynamicQuery = CONCAT (N'
set @Sample =
(
select t.ColumnData
from ', @CurrentTableName, ' AS x
where x.', @CurrentColumnName, ' IS NOT NULL
for xml path(''''), type
).value(''.'',''nvarchar(max)'')
)t')
谢谢你的帮助。
正确的问题是:
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,'''')')