【发布时间】:2016-09-01 13:56:47
【问题描述】:
我需要将多行文本连接成 1 个字符串。我不想使用 FOR XML PATH,因为我需要纯文本,而不是 XML。 我认为使用递归 CTE 可以解决问题,但我需要在 CTE 中使用子查询来创建基本案例,并且 CTE 中的递归案例无法识别子查询表。
这是我的 SQL:
DECLARE @EndCreateTableScript varchar(20) = ') ON [PRIMARY] ';
DECLARE @NewLine varchar(2) = CHAR(13) + CHAR(10);
DECLARE @createTableScript varchar(max)
SET @createTableScript = 'CREATE TABLE ['
;WITH CTE
AS (
SELECT ScriptTbl2.RowNumber, ScriptTbl2.CreateTableStart, ScriptTbl2.ColumnScript, ScriptTbl2.EndTableScript
FROM
(
SELECT ROW_NUMBER() OVER (PARTITION BY TableName ORDER BY TableName) AS RowNumber, TableName,
CreateTableStart, ColumnTextStart + DataSizeText + ColumnNullText + @NewLine AS ColumnScript, @EndCreateTableScript + TextImageScript AS EndTableScript
FROM
(
SELECT DISTINCT SchemaName, TableName, @createTableScript + SchemaName + '].[' + TableName + '] ( ' + @NewLine AS CreateTableStart,
'[' +ColName + '] [' + DataType + '] ' AS ColumnTextStart,
CASE WHEN DataType in ('bit', 'int', 'money', 'datetime') THEN ' '
WHEN DataType in ('numeric', 'decimal') THEN '(' + DataTypePrecision + ', ' + DataTypeScale + ') '
WHEN CAST(DataTypeMaxLength AS INT) = -1 THEN '(max) '
WHEN DataType in ('varchar', 'varbinary') THEN '('+ DataTypeMaxLength +') '
WHEN DataType = 'nvarchar' THEN '('+ CAST(CAST(DataTypeMaxLength AS INT)/2 AS varchar(5)) +') '
END AS DataSizeText,
CASE IsColumnNullable WHEN '0' THEN 'NOT NULL,' ELSE 'NULL,' END AS ColumnNullText,
CASE WHEN TextImageFileGroup IS NOT NULL THEN 'TEXTIMAGE_ON [' + TextImageFileGroup + ']' ELSE '' END AS TextImageScript
FROM #DBObjectsToAdd
) AS ScriptTbl
) AS ScriptTbl2
WHERE RowNumber = 1
UNION ALL
SELECT CTE.RowNumber, CTE.CreateTableStart, CTE.ColumnScript + ' ' + ScriptTbl2.ColumnScript, CTE.EndTableScript
FROM CTE JOIN #DBObjectsToAdd ScriptTbl ON CTE.RowNumber = ScriptTbl2.RowNumber + 1
)
SELECT *
FROM CTE
问题是子查询表 ScriptTbl2 在递归情况下无法识别。我该如何解决这个问题?
目标是将 ColumnScript 文本连接成每个表格的 1 行文本。
更新 数据并不重要。我只想将多行文本连接成 1 行。 1 表 1 文本 1 2 表 1 文本 2 3 表 1 文本 3 4 表 2 文本 4 5 表2文字5
使用 CTE 递归或其他一些类型的查询更改为: 1 表 1 文本 1 文本 2 文本 3 2 表2 文本4 文本5
更新 我创建了一个临时表,需要 Row_Number 进行递归和 3 个文本字段。
CREATE TABLE #TableScripts(RowNumber int, TableStart varchar(100), ColumnScript varchar(max), TableEnd varchar(100))
这是添加数据的SELECT 查询。
SELECT RowNumber, TableName, CreateTableStart, ColumnScript, TextImageScript
FROM
(
SELECT DISTINCT ROW_NUMBER() OVER (PARTITION BY TableName ORDER BY TableName) AS RowNumber,
SchemaName, TableName, @createTableScript + SchemaName + '].[' + TableName + '] ( ' + @NewLine AS CreateTableStart,
('[' +ColName + '] [' + DataType + '] ') +
(CASE WHEN DataType in ('bit', 'int', 'money', 'datetime') THEN ' '
WHEN DataType in ('numeric', 'decimal') THEN '(' + DataTypePrecision + ', ' + DataTypeScale + ') '
WHEN CAST(DataTypeMaxLength AS INT) = -1 THEN '(max) '
WHEN DataType in ('varchar', 'varbinary') THEN '('+ DataTypeMaxLength +') '
WHEN DataType = 'nvarchar' THEN '('+ CAST(CAST(DataTypeMaxLength AS INT)/2 AS varchar(5)) +') '
END) +
(CASE IsColumnNullable WHEN '0' THEN 'NOT NULL,' ELSE 'NULL,' END) + @NewLine AS ColumnScript,
@EndCreateTableScript + (CASE WHEN TextImageFileGroup IS NOT NULL THEN 'TEXTIMAGE_ON [' + TextImageFileGroup + ']' ELSE '' END) AS TextImageScript
FROM #DBObjectsToAdd
) AS ScriptTbl
ORDER BY TableName
出于某种原因,将ROW_NUMBER 函数添加到查询中会将其中1 个表的行数从2(它只有2 列)增加到32。
【问题讨论】:
-
为什么不想在这里使用 FOR XML?这就是做这种事情的方法。
-
XML 创建的文本在有新行或 '' 时添加那些特殊字符
-
能否请您发布表格数据和预期输出?
-
文本将是一个创建表的 sql 脚本。
-
我在上面添加了当前表格数据的样本。
标签: sql-server recursion