2016-09-01 28 views
0

我需要將文本行連接成1個字符串。我不想使用FOR XML PATH,因爲我需要純文本而不是XML。 我認爲使用遞歸CTE將做的伎倆,但我需要在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行文本。

UPDATE 數據並不重要。我只是想將多行文本連接成1行。 1表1文本1 2表1文本2 3表1文本3 4表2文本4 5表2 Text5

使用CTE遞歸或一些其它類型的查詢變更的: 1表1文本1文本2文本3 2表2文本4 Text5

UPDATE 我創建了一個需要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.

+1

爲什麼你不想在這裏FOR XML使用?這是做這種事情的方法。 –

+0

由XML創建的文本在有新行或'<' or '>' –

+0

時會添加這些特殊字符您可以發佈表數據和預期輸出嗎? –

回答

0

我認爲這只是一個遞歸部分的JOIN引用不好,但這不是問題。

您正在引用CTE,它可以被認爲是遞歸的前一次迭代。但是對於你的「當前迭代」,你試圖引用ScriptTbl2,但是ScriptTbl2只存在於「錨點」查詢中 - 你必須用ROW_NUMBER()等重做該查詢,以在遞歸部分構建你自己的ScriptTbl2 。

也許是這樣的:

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 (
     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 
    ) AS ScriptTbl3 
    ON ScriptTbl3.RowNumber = CTE.RowNumber + 1 --you want each iteration to increase, right? 
) 
SELECT * 
FROM CTE 
+0

當我做了更改,'RowNumber'不能解決,因爲它不存在和'SELECT''中不存在'ScriptTbl2'# –

+0

@GloriaSantin回答完全更新,看看是否有幫助 – SlimsGhost

+0

當然你可以重構普通查詢到一個視圖等,但試圖重用錨點查詢是立即要解決的問題,我想 – SlimsGhost