将EXEC语句作为参数传递给APPLY

时间:2012-04-10 14:54:54

标签: sql sql-server-2008 tsql

我需要从具有相同模式的表的多个数据库中获取数据。为此,我在其中一个数据库中为这些表创建了同义词。数据库的数量将随着时间的推移而增长。因此,获取数据的过程应该是灵活的。我编写了以下代码片段来解决问题:

WHILE @i < @count
BEGIN
    SELECT @synonymName = [Name]
    FROM Synonyms
    WHERE [ID] = @i
        SELECT @sql = 'SELECT TOP (1) * 
                FROM [dbo].[synonym' + @synonymName + '] as syn
                WHERE [syn].[Id] = tr.[Id]
                ORDER BY [syn].[System.ChangedDate] DESC'

        INSERT INTO @tmp
        SELECT  col1, col2
        FROM
        (
            SELECT * FROM TableThatHasRelatedDataFromAllTheSynonyms
            WHERE [Date] > @dateFrom 
        ) AS tr         
        OUTER APPLY (EXEC(@sql)) result 

    SET @i = @i + 1
END

我也很欣赏有关如何简化解决方案的任何想法。

2 个答案:

答案 0 :(得分:1)

实际上,最好将所有表中的数据导入到一个表中(可能还有源表名称的附加列)并使用它。可以通过SP或SSIS包进行导入。

关于初始问题 - 您可以通过TVF包装器为exec语句实现它(在exec ..内部)。

UPD:正如评论中所注意到的,exec在TVF内部无效。所以,如果你真的不想改变数据库结构,你需要使用很多表我建议:

  1. 或者从同义词***表中选择所有数据到变量(因为我看到你只选择一行)并使用它们
  2. 或者为完整语句准备动态SQL(带插入等),并在此处使用临时表而不是表变量。

答案 1 :(得分:0)

我的解决方案非常简单。只是将所有查询放到字符串并执行它。不幸的是,它比所有同义词的代码复制/过去慢3倍。

WHILE @i < @count
BEGIN
    SELECT @synonymName = [Name]
    FROM Synonyms
    WHERE [ID] = @i
        SELECT @sql = 'SELECT  col1, col2
        FROM
        (
            SELECT * FROM TableThatHasRelatedDataFromAllTheSynonyms
            WHERE [Date] > ''' + @dateFrom + '''
        ) AS tr         
        OUTER APPLY (SELECT TOP (1) * 
                FROM [dbo].[synonym' + @synonymName + '] as syn
                WHERE [syn].[Id] = tr.[Id]
                ORDER BY [syn].[System.ChangedDate] DESC) result'

        INSERT INTO @tmp
        EXEC(@sql)

    SET @i = @i + 1
END