2015-11-04 49 views
2

在我的數據庫的4個不同表格中找到數以千計的代碼。我已經創建了一個臨時表來插入所有的代碼和相應的表名,可以找到該代碼。作爲一個例子,我展示了臨時表的一小部分。使用動態查詢字符串連接多個表格

代碼 | table_name

DA | StatsCanCensus2011_1

DWAPT5L | StatsCanCensus2011_3

DWAPT5O | StatsCanCensus2011_3

DWDUP | StatsCanCensus2011_3

DWMOVA | StatsCanCensus2011_3

我想寫一個查詢,我可以動態地選擇代碼,並在選擇的代碼來自不同的表格時加入表格。我能夠輕鬆地爲2張桌子做到這一點,但是當有3張或4張時,它無法工作。

下面將給出的結果,我需要時2個表需要被接合:

declare @code nvarchar(15), @tblname nvarchar(30), @strSQL nvarchar(max), @strWhere nvarchar(max) 

DECLARE db_cursor CURSOR FOR 
select code, table_name from tmpVarList2 

OPEN db_cursor 
FETCH NEXT FROM db_cursor INTO @code, @tblname 
set @strSQL='select' 
WHILE @@FETCH_STATUS = 0 
BEGIN 
     print @code + @tblname 
     set @[email protected] + ' ' + @code + ',' 
     FETCH NEXT FROM db_cursor INTO @code, @tblname 
END 

set @strSQL=left(@strSQL, len(@strSQL)-1) 

print @strSQL 
CLOSE db_cursor 
DEALLOCATE db_cursor 


set @[email protected] + ' from' 
set @strWhere=' where ' 
DECLARE db_cursor CURSOR FOR 
select distinct table_name from tmpVarList2 

OPEN db_cursor 
FETCH NEXT FROM db_cursor INTO @tblname 

WHILE @@FETCH_STATUS = 0 
BEGIN 
     print @code + @tblname 
     set @[email protected] + ' ' + @tblname + ',' 
     set @[email protected] + @tblname + '.da=' 
     FETCH NEXT FROM db_cursor INTO @tblname 
END 

set @strSQL=left(@strSQL, len(@strSQL)-1) 
set @strWhere=left(@strWhere, len(@strWhere)-1) 
set @[email protected] + @strWhere 


SELECT @strSQL 

CLOSE db_cursor 
DEALLOCATE db_cursor 

結果:

select DA, DWAPT5L, DWAPT5O, DWDUP, DWMOVA 
from StatsCanCensus2011_1, StatsCanCensus2011_3 
where StatsCanCensus2011_1.da=StatsCanCensus2011_3.da 

結果的實施例時,有3個表加入:

select DA, DWAPT5L, FMCLNOCH,FMCPINTO, FMCPSZAV, FMCPTIAV, FMCPTIME, FMHHTOT 
from StatsCanCensus2011_1, StatsCanCensus2011_3, StatsCanNHS2011_4 
where StatsCanCensus2011_1.da=StatsCanCensus2011_3.da=StatsCanNHS2011_4.da 
+1

我建議你重寫使用'JOIN ... ON'而不是用逗號分隔表格。 –

回答

1

使用遊標來組裝和執行動態SQL查詢是雄心勃勃的,但這意味着執行路徑永遠不會被緩存。此外,如果這些是大型表格(因爲普查數據傾向於),您可能會遇到一些優化的實際挑戰。隨着標準DBA絆腳石,它實際上是一個非常有趣的想法,因爲它聽起來很糟糕,但實際上並不那麼糟糕(因爲光標從不觸及數據)。

我認爲你是正確的方法,但你試圖讓每個光標做得太多。有三個部分可以用於你想要的查詢,一個帶有列表的select語句,一個帶有連接表列表的from語句,以及一個包含連接這些表的邏輯的where語句(隱式地加入它們而不是明確地這樣做) 。那麼爲什麼不三個光標,每個都專注於一個特定的區域。它允許每個遊標的構造更簡單,然後您可以組合最終結果。

declare @select_Code varchar(max) 
declare @Select_column varchar(max) 
declare @selectloop int 
declare @From_Code varchar(max) 
declare @From_Column varchar(max) 
declare @FromLoop int 
declare @Where_Code Varchar(max) 

create table #temp (columnname varchar(128), tablename Varchar(128)) 

insert into #temp 
select 'ColumnA', 'TableA' 
union 
select 'Columnb', 'TableB' 
union 
select 'Columnc', 'TableC' 

--drop table #temp 

set @select_Code = 'Select ' 
set @selectloop = 0 

declare select_cursor cursor for 
    select columnname from #temp 

Open select_cursor 

fetch next from select_cursor 
into @Select_column 


while @@FETCH_STATUS = 0 
begin 
set @select_Code = @select_Code + (select case when @selectloop > 0 then ', ' else '' end as CommaOrNot) + @Select_column 
set @selectloop = @selectloop + 1 

fetch next from select_cursor into @Select_column 
end 
close select_cursor 
deallocate select_cursor 

set @From_Code = ' From ' 
set @FromLoop = 0 

declare From_cursor cursor for 
    select tablename from #temp 

Open From_cursor 

fetch next from From_cursor 
into @from_column 


while @@FETCH_STATUS = 0 
begin 
set @From_Code = @From_Code + (select case when @FromLoop > 0 then ', ' else '' end as CommaOrNot) + @from_column 
set @FromLoop = @FromLoop + 1 

fetch next from From_cursor into @from_column 
end 
close From_cursor 
deallocate From_cursor 

select @select_Code + @From_Code 

我讓你做的where子句,因爲我不知道,如果你是菊花鏈連接它們,或者如果他們全部加入回到第一個表,無論是它遵循相同的模式,你只需要將案例陳述更新爲類似的東西;

case when @whereloop > 0 and @whereloop % 2 = 0 then ' and ' 
    when @whereloop > 0 and @whereloop % 2 = 1 then ' = ' 
    else '' end as EqualsOrNewJoin 

對於選擇和語句我使用循環數來確定,如果我需要在現有代碼和新的部分之間的CONCAT前加逗號。對於where子句有點棘手,它需要在x = y和y = z的地方。所以我使用mod來獲取循環數的其餘部分,以確定循環是奇數還是一旦我們超過第一個循環(循環0)。如果它很奇怪(循環1是第二個條目),我知道它們之間應該有一個=符號,例如:Loop0 = loop1。如果甚至我知道我們正在建立一個新的條件,所以我需要使用和。無論如何,希望這有助於,並讓我知道如果你有任何問題。

+0

感謝您的評論,它已經幫了很多。我正在通過一些糾結工作,並會讓你知道它是怎麼回事!通過將每個任務分解到不同的光標來簡化事情使其更容易遵循。 –