Sql 在联接中使用动态查询创建的临时表

Sql 在联接中使用动态查询创建的临时表,sql,sql-server,sql-server-2008,dynamic-sql,temp-tables,Sql,Sql Server,Sql Server 2008,Dynamic Sql,Temp Tables,我有一个动态查询,它从另一个数据库获取某些记录(数据库服务器和数据库名称是变量,因此使用动态查询) 下面是查询 DECLARE @SQLString NVARCHAR(1000) set @SQLString=' select distinct(select distinct ( select * from ( ------- Inner query (It is more complex than this) select lAccountId, sAccount

我有一个动态查询,它从另一个数据库获取某些记录(数据库服务器和数据库名称是变量,因此使用动态查询)

下面是查询

DECLARE @SQLString NVARCHAR(1000)      
set @SQLString='
select distinct(select distinct
(
select * from
(
    ------- Inner query (It is more complex than this)

    select lAccountId, sAccountName 
    from '+@DatabaseServer+'.'+@DatabaseName+'.dbo.AccDetails  
    where lAccountId = 10  
    union  
    select lAccountId, sAccountName 
    from '+@DatabaseServer+'.'+@DatabaseName+'.dbo.AccHistoryDetails  
    where lAccountId = 10 
) A
    for xml raw(''Account''), ROOT(''Accounts''), ELEMENTS 
)) as AccXmlValue,
lAccountId as AccountId      
into       
 #tmpAccDetails
from       
 AccountDetails      
where       
 AccountDetails.laccountID in (''10,11'')'     

EXECUTE (@SQLString)    

----- This is the final SQL statement (It is more complex than this)

select * from 
MainAccTable M
inner join #tmpAccDetails tmp on M.lAccountId = tmp.AccountId 
我想将
#tmpAccDetails
mainactable
结合使用

  • 如何实现这一点,因为临时表不在动态SQL之外的范围内
  • 使用全局临时表可以解决这个问题,但是在这个场景中使用它会是一个好主意吗
  • 我的问题与此类似,只是我必须在join中使用
    #tmpAccDetails
    表,而不是一次从中选择数据


    任何帮助都将不胜感激。谢谢。

    如果您先创建临时表,我想您会没事的

    例如

    DECLARE @SQLString NVARCHAR(1000)      
    
    CREATE TABLE #tmpAccDetails
    (lAccountId int, 
     sAccountName  NVArchar(100)
    );
    
    
    set @SQLString='
    select distinct(select distinct
    (
    select * from
    (
        ------- Inner query (It is more complex than this)
    
        select lAccountId, sAccountName 
        from '+@DatabaseServer+'.'+@DatabaseName+'.dbo.AccDetails  
        where lAccountId = 10  
        union  
        select lAccountId, sAccountName 
        from '+@DatabaseServer+'.'+@DatabaseName+'.dbo.AccHistoryDetails  
        where lAccountId = 10 
    ) A
        for xml raw(''Account''), ROOT(''Accounts''), ELEMENTS 
    )) as AccXmlValue,
    lAccountId as AccountId      
    into       
     #tmpAccDetails
    from       
     AccountDetails      
    where       
     AccountDetails.laccountID in (''10,11'')'     
    
    EXECUTE (@SQLString)    
    
    Select * from 
    MainAccTable M
    inner join #tmpAccDetails tmp on M.lAccountId = tmp.AccountId 
    

    如果你先创建临时表,我想你会没事的

    例如

    DECLARE @SQLString NVARCHAR(1000)      
    
    CREATE TABLE #tmpAccDetails
    (lAccountId int, 
     sAccountName  NVArchar(100)
    );
    
    
    set @SQLString='
    select distinct(select distinct
    (
    select * from
    (
        ------- Inner query (It is more complex than this)
    
        select lAccountId, sAccountName 
        from '+@DatabaseServer+'.'+@DatabaseName+'.dbo.AccDetails  
        where lAccountId = 10  
        union  
        select lAccountId, sAccountName 
        from '+@DatabaseServer+'.'+@DatabaseName+'.dbo.AccHistoryDetails  
        where lAccountId = 10 
    ) A
        for xml raw(''Account''), ROOT(''Accounts''), ELEMENTS 
    )) as AccXmlValue,
    lAccountId as AccountId      
    into       
     #tmpAccDetails
    from       
     AccountDetails      
    where       
     AccountDetails.laccountID in (''10,11'')'     
    
    EXECUTE (@SQLString)    
    
    Select * from 
    MainAccTable M
    inner join #tmpAccDetails tmp on M.lAccountId = tmp.AccountId 
    

    只需更改语句的顺序,如下所示:

    DECLARE @SQLString NVARCHAR(1000)   
    
    set @SQLString='
    select distinct(select distinct
    (
    select * from
    (
        ------- Inner query (It is more complex than this)
    
        select lAccountId, sAccountName 
        from '+@DatabaseServer+'.'+@DatabaseName+'.dbo.AccDetails  
        where lAccountId = 10  
        union  
        select lAccountId, sAccountName 
        from '+@DatabaseServer+'.'+@DatabaseName+'.dbo.AccHistoryDetails  
        where lAccountId = 10 
    ) A
        for xml raw(''Account''), ROOT(''Accounts''), ELEMENTS 
    )) as AccXmlValue,
    lAccountId as AccountId      
    into       
     #tmpAccDetails
    from       
     AccountDetails      
    where       
     AccountDetails.laccountID in (''10,11'')'     
    
    
    CREATE TABLE #tmpAccDetails
    (lAccountId int, 
     sAccountName  NVArchar(100)
    );
    
    INSERT INTO #tmpAccDetails
    EXEC sp_executesql @sSQL    
    
    Select * from 
    MainAccTable M
    inner join #tmpAccDetails tmp on M.lAccountId = tmp.AccountId 
    

    只需更改语句的顺序,如下所示:

    DECLARE @SQLString NVARCHAR(1000)   
    
    set @SQLString='
    select distinct(select distinct
    (
    select * from
    (
        ------- Inner query (It is more complex than this)
    
        select lAccountId, sAccountName 
        from '+@DatabaseServer+'.'+@DatabaseName+'.dbo.AccDetails  
        where lAccountId = 10  
        union  
        select lAccountId, sAccountName 
        from '+@DatabaseServer+'.'+@DatabaseName+'.dbo.AccHistoryDetails  
        where lAccountId = 10 
    ) A
        for xml raw(''Account''), ROOT(''Accounts''), ELEMENTS 
    )) as AccXmlValue,
    lAccountId as AccountId      
    into       
     #tmpAccDetails
    from       
     AccountDetails      
    where       
     AccountDetails.laccountID in (''10,11'')'     
    
    
    CREATE TABLE #tmpAccDetails
    (lAccountId int, 
     sAccountName  NVArchar(100)
    );
    
    INSERT INTO #tmpAccDetails
    EXEC sp_executesql @sSQL    
    
    Select * from 
    MainAccTable M
    inner join #tmpAccDetails tmp on M.lAccountId = tmp.AccountId 
    
    您是否考虑过使用“OPENDATASOURCE”从另一个数据库访问数据?

    可以使用此方法连接来自不同数据库的表

        SELECT *
        FROM MainAccTable M
        INNER JOIN OPENDATASOURCE ('SQLOLEDB', 'Data Source=@myInstance;User ID=@myUserName;Password=@myPassword).XXX.dbo.AccountId AS tmp 
    ON tmp.AccountId = M.lAccountId 
    
    您是否考虑过使用“OPENDATASOURCE”从另一个数据库访问数据?

    可以使用此方法连接来自不同数据库的表

        SELECT *
        FROM MainAccTable M
        INNER JOIN OPENDATASOURCE ('SQLOLEDB', 'Data Source=@myInstance;User ID=@myUserName;Password=@myPassword).XXX.dbo.AccountId AS tmp 
    ON tmp.AccountId = M.lAccountId 
    

    我自己解决了这个问题,并将答案张贴在这里,以便其他人也能从中受益

    DECLARE @SQLString NVARCHAR(MAX)      
    set @SQLString='
    select distinct(select distinct
    (
    select * from
    (
    ------- Inner query (It is more complex than this)
    
    select lAccountId, sAccountName 
    from '+@DatabaseServer+'.'+@DatabaseName+'.dbo.AccDetails  
    where lAccountId = 10  
    union  
    select lAccountId, sAccountName 
    from '+@DatabaseServer+'.'+@DatabaseName+'.dbo.AccHistoryDetails  
    where lAccountId = 10 
    ) A
    for xml raw(''Account''), ROOT(''Accounts''), ELEMENTS 
    )) as AccXmlValue,
    lAccountId as AccountId      
    from       
     '+@DatabaseServer+'.'+@DatabaseName+'.dbo.AccountDetails     
    where       
     laccountID in (''10,11'')' 
    
    ---- Create temp table here
    CREATE TABLE #tmpAccDetails 
    (
    AccXmlValue NVarchar(max),
    AccountId int 
    );
    
    ---- Insert into temp table here
    INSERT INTO #tmpAccDetails EXECUTE (@SQLString)
    
    ---- Select from temp table here
    Select * from 
    MainAccTable M
    inner join #tmpAccDetails tmp on M.lAccountId = tmp.AccountId 
    

    我自己解决了这个问题,并将答案张贴在这里,以便其他人也能从中受益

    DECLARE @SQLString NVARCHAR(MAX)      
    set @SQLString='
    select distinct(select distinct
    (
    select * from
    (
    ------- Inner query (It is more complex than this)
    
    select lAccountId, sAccountName 
    from '+@DatabaseServer+'.'+@DatabaseName+'.dbo.AccDetails  
    where lAccountId = 10  
    union  
    select lAccountId, sAccountName 
    from '+@DatabaseServer+'.'+@DatabaseName+'.dbo.AccHistoryDetails  
    where lAccountId = 10 
    ) A
    for xml raw(''Account''), ROOT(''Accounts''), ELEMENTS 
    )) as AccXmlValue,
    lAccountId as AccountId      
    from       
     '+@DatabaseServer+'.'+@DatabaseName+'.dbo.AccountDetails     
    where       
     laccountID in (''10,11'')' 
    
    ---- Create temp table here
    CREATE TABLE #tmpAccDetails 
    (
    AccXmlValue NVarchar(max),
    AccountId int 
    );
    
    ---- Insert into temp table here
    INSERT INTO #tmpAccDetails EXECUTE (@SQLString)
    
    ---- Select from temp table here
    Select * from 
    MainAccTable M
    inner join #tmpAccDetails tmp on M.lAccountId = tmp.AccountId 
    


    不,这不起作用。数据不会以这种方式插入临时表。它不会给出任何错误,它返回空结果。这表明它正在插入某个位置,或者动态sql没有返回行。我对这一点很好奇……。我想,在动态查询之后,我将试验temp表是否超出范围。你知道实现这个功能的其他方法吗?我已经自己解决了这个问题并发布了答案+感谢你的时间和努力:)不,这不起作用。数据不会以这种方式插入临时表。它不会给出任何错误,它返回空结果。这表明它正在插入某个位置,或者动态sql没有返回行。我对这一点很好奇……。我想,在动态查询之后,我将试验temp表是否超出范围。你知道实现这个功能的其他方法吗?我已经自己解决了这个问题并发布了答案+1感谢您的时间和精力:)这里是什么?@ser_nicky如果我将其作为查询运行,它会起作用,如果它放在存储过程中,它就不起作用。@Senjuti Mahapatra-哦,您没有提到这部分代码应该在存储过程中运行。由于您尚未提供SP详细信息,请查看:@ser_nicky:您的回答几乎正确,帮助我解决了问题。我自己解决了这个问题,并把答案贴了出来+感谢您的时间和精力。这里是什么?@ser_nicky如果我将其作为查询运行,它会起作用,如果它放在存储过程中,它就不起作用。@Senjuti Mahapatra-哦,您没有提到这部分代码应该在存储过程中运行。由于您尚未提供SP详细信息,请查看:@ser_nicky:您的回答几乎正确,帮助我解决了问题。我自己解决了这个问题,并把答案贴了出来+感谢你的时间和努力。