生成动态查询

时间:2015-10-16 10:16:05

标签: sql sql-server sql-server-2012

我想动态生成一个查询。我用一些条件写了它;

DECLARE @NewLineChar AS CHAR(2) = CHAR(13) + CHAR(10)

DECLARE @MyTable TABLE(
    FormTypeID int NOT NULL,
    TableName NVARCHAR(100),
    pk NVARCHAR(50));

INSERT INTO @MyTable( FormTypeID, TableName, pk )
    VALUES  ( 0, N'Table1', 'ParentID'),
            ( 5, N'Table2', 'ID'),
            ( 5, N'Table3', 'ParentID'),
            ( 5, N'Table4','ParentID'),
            ( 3, N'Table5','ParentID')  

DECLARE @SQLJoin  varchar(8000) = 'LEFT JOIN (SELECT t.* FROM ParentTable t ' + @NewLineChar,
        @pk nvarchar(100);


SELECT @SQLJoin += ' INNER JOIN ' + TableName +' ON ' + TableName + '.' + pk + ' = t.ID' + @NewLineChar FROM @MyTable   
    WHERE FormTypeID IN (0,5)

PRINT @SQLJoin + ')';

结果是:

LEFT JOIN (SELECT t.* FROM ParentTable t 
 INNER JOIN Table1 ON Table1.ParentID = t.ID
 INNER JOIN Table2 ON Table2.ID = t.ID
 INNER JOIN Table3 ON Table3.ParentID = t.ID
 INNER JOIN Table4 ON Table4.ParentID = t.ID
)

我希望它看起来像嵌套连接取决于FormTypeID:

LEFT JOIN (SELECT t.* FROM ParentTable t 
 INNER JOIN Table1 ON Table1.ParentID = t.ID)
LEFT JOIN (SELECT t.* FROM ParentTable t 
 INNER JOIN Table2 ON Table2.ID = t.ID
 INNER JOIN Table3 ON Table3.ParentID = t.ID
 INNER JOIN Table4 ON Table4.ParentID = t.ID
)

2 个答案:

答案 0 :(得分:0)

只需选择两次:一次用于FormTypeID = 0,一次用于FormTypeID = 5

这应该会给你想要的结果

set nocount on
DECLARE @NewLineChar AS CHAR(2) = CHAR(13) + CHAR(10)

DECLARE @MyTable TABLE(
    FormTypeID int NOT NULL,
    TableName NVARCHAR(100),
    pk NVARCHAR(50));

INSERT INTO @MyTable( FormTypeID, TableName, pk )
    VALUES  ( 0, N'Table1', 'ParentID'),
            ( 5, N'Table2', 'ID'),
            ( 5, N'Table3', 'ParentID'),
            ( 5, N'Table4','ParentID'),
            ( 3, N'Table5','ParentID')  

DECLARE @SQLJoin  varchar(MAX) = 'LEFT JOIN (SELECT t.* FROM ParentTable t ' + @NewLineChar, @pk nvarchar(100);

SELECT @SQLJoin += ' INNER JOIN ' + TableName +' ON ' + TableName + '.' + pk + ' = t.ID)' + @NewLineChar FROM @MyTable WHERE FormTypeID = 0

SELECT @SQLJoin += 'LEFT JOIN (SELECT t.* FROM ParentTable t ' + @NewLineChar
SELECT @SQLJoin += ' INNER JOIN ' + TableName +' ON ' + TableName + '.' + pk + ' = t.ID' + @NewLineChar FROM @MyTable WHERE FormTypeID = 5
SELECT @SQLJoin += ')';
PRINT @SQLJoin;

PRINT '--' + @NewLineChar

DECLARE @SQLOutput   varchar(8000) = '';

select @SQLOutput += 'LEFT JOIN (SELECT t.* FROM ParentTable t '  + @NewLineChar
select @SQLOutput += ' INNER JOIN Table1 ON Table1.ParentID = t.ID)'  + @NewLineChar
select @SQLOutput += 'LEFT JOIN (SELECT t.* FROM ParentTable t '  + @NewLineChar 
select @SQLOutput += ' INNER JOIN Table2 ON Table2.ID = t.ID'  + @NewLineChar
select @SQLOutput += ' INNER JOIN Table3 ON Table3.ParentID = t.ID'  + @NewLineChar
select @SQLOutput += ' INNER JOIN Table4 ON Table4.ParentID = t.ID'  + @NewLineChar
select @SQLOutput += ')';


print @SQLOutput

select case when @SQLOutput = @SQLJoin then 1 else 0 end

答案 1 :(得分:0)

我想我找到了解决方案

DECLARE @NewLineChar AS CHAR(2) = CHAR(13) + CHAR(10), @Param NVARCHAR(100) = '0,5';

DECLARE @MyTable TABLE(
    FormTypeID int NOT NULL,
    TableName NVARCHAR(100),
    PK NVARCHAR(50));

INSERT INTO @MyTable(FormTypeID, TableName, PK )
    VALUES  ( 0, N'Table1', 'ParentID'),
            ( 5, N'Table2', 'ID'),
            ( 5, N'Table3', 'ParentID'),
            ( 5, N'Table4','ParentID'),
            ( 3, N'Table5','ParentID')


DECLARE @SQLString varchar(8000) = '',
        @SQLJoin  varchar(8000) = 'LEFT JOIN (SELECT t.* FROM ParentTable t ' + @NewLineChar;

SELECT @SQLString += 
    @SQLJoin + 
    (SELECT
        ' INNER JOIN ' + A.TableName +' ON ' + A.TableName + '.' + A.PK + ' = t.ID' + @NewLineChar
        FROM @MyTable AS A
    WHERE A.FormTypeID = CAST(B.Data AS INT) FOR XML PATH (''), TYPE).value('.', 'varchar(max)') + ')'
FROM dbo.Split(@Param,',') AS B

PRINT @SQLString

Split只是表值函数,它导出2个参数并以表格格式

返回数据