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

时间:2017-02-01 10:09:03

标签: 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, 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的加入中使用MainAccTable

  1. 如何实现这一点,因为临时表不在动态SQL之外的范围内?
  2. 使用Global Temp表解决了这个问题,但在这种情况下使用它会是个好主意吗?
  3. 我的问题类似于此Question,除了我必须在联接中使用#tmpAccDetails表,而不是一次性从中选择数据。

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

5 个答案:

答案 0 :(得分:1)

如果你先创建临时表,我认为你会好的。

...例如

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 

答案 1 :(得分:1)

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

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 

答案 2 :(得分:0)

BEGIN TRAN  
    DECLARE @SQLString NVARCHAR(1000)      

      CREATE TABLE #tmpAccDetails
      (lAccountId int, 
       sAccountName  NVArchar(100)
      );


      set @SQLString=' INSERT INTO  #tmpAccDetails

      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 


      RollBAck Tran

答案 3 :(得分:0)

您是否考虑过" OPENDATASOURCE"从另一个数据库访问数据? https://msdn.microsoft.com/fr-fr/library/ms179856.aspx

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

    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 

答案 4 :(得分:0)

我自己已经解决了问题并在此处发布了答案,以便其他人可以从中受益。

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