SQL Dynamische View (Ansicht)

Squicky

Lt. Commander
Registriert
Sep. 2002
Beiträge
1.422
Hallo

Ich stehe vor einem etwas schwerem Problem: Es wir eine „dynamische“ View (Ansicht) gebraucht. (Eine View ist im Grunde eine abgespeicherte select Abfrage, die man beim Lesen wie eine Tabelle, ansprechen kann.)

In dieser select abfragen, sollen Ergebnisse von mehreren select Abfragen zusammengefasst werden.
Kein Problem: UNION ALL

Select name from tab1
UNION ALL
Select name from tab2
UNION ALL
Select name from tab2

Das dynamische aber ist, dass die Anzahl der Tabellen, aus der die Namen ausgelesen und zusammen gefasst werden sollen nicht immer gleich ist.

Es gibt eine Tabelle (TabIndex) mit den Spalten: TabID und TabName. Für das obige Beispiel, würde die TabIndex drei Datensätze haben mit den Spalteninhalten: tab1, tab2 und tab3.

Gearbeitet wird mit MS SQL Server 2008

Ich dachte, dass ich mir den eigentlichen select Befehl (z.B: „Select name from tab1“) in einen String („StrSQL“) zusammen baue, und diesen dann per „EXEC StrSQL“ ausführe.
Dies würde ich dann in einer Schleife (CURSON) machen und den Inahlt von TabIndex durchlaufen. Für jeden Datensatz bzw. für jeden TabName in TabIndex würde ich „EXEC ‘select name from ‘ & TabName “ machen. Aber wie fasse ich dann diese Rückgaben zusammen und lasse sie dann als eine große gemeinsame Rückgabe eines select bzw. View ausgeben?

Danke
 
hmm also mit einem count kannst du schoneinmal die zeilen deiner TabIndex zählen.

dan einfach ne variable seten mit dem ergebniss vom count, das ganze in einer while schleife packen oder mit if exists oder so abfragen...viel erfolg

mfg
 
Dies würde ich mit dem Cursor erledigt.
Aber wie füge ich die einzelnen Rückgaben zusammen?
Das ist die Frage!?!
 
Zuletzt bearbeitet:
Ich kanns dir leider nicht sagen, da ich nich so den Plan davon hab bin kein AE xD
Was du glaube ich machen must ist eine Procedure zu erstellen die deine View aufruft oder umgekehrt!?

mfg
 
Ich kenne nur den Weg über eine temporäre Tabelle, die alle Spalten des neuen Resultsets enthält und dann nach einander mit Inserts gefüllt wird. Der angepasste Code wäre sicher in in einer Stored Procedure gut aufgehoben:

Code:
SELECT NAME INTO #TempTable FROM Tab1 WHERE 1=2
INSERT INTO #TempTable(NAME) EXEC N'SELECT NAME FROM Tab1'
INSERT INTO #TempTable(NAME) EXEC N'SELECT NAME FROM Tab2'
INSERT INTO #TempTable(NAME) EXEC N'SELECT NAME FROM Tab3'
SELECT * FROM #TempTable
DROP TABLE #TempTable

Dann das SELECT um das Gesamte in die Außenwelt zu feuern und zum Schluß die temporäre Tabelle wieder droppen.

Aber INSERT und EXEC zusammen kannst du auf temporären Tabellen (keine Tabellenvariablen!) in einer Stored Procedure verwenden. Bei Table Functions gehts nicht. Gleiches gilt, vermute ich, auch für die temporären Tabellen bzw. das CREATE dieser. Den Aufruf der Stored Procedure wirst du wohl kaum in eine View einbauen können. Direktes weiterverarbeiten des Resultsets außerhalb der Stored Procedure in TSQL wirst du sicher auch nur über ein INSERT INTO ... EXEC erreichen, vorrausgesetzt deine Stored Procedure gibt nur dieses eine Resultset zurück.

Alternativ könntest du dir auch ein großes UNION SELECT zusammenstellen, wärst dann aber auf 4000 Zeichen begrenzt (Maximum bei NVARCHAR).

Code:
DECLARE @sCmd NVARCHAR(4000)
SELECT @sCmd = ISNULL(@sCmd + N' UNION ', N' ') + N'SELECT NAME FROM ' + TabName FROM TabIndex
EXEC @sCmd

Viel Spaß damit und viel Erfolg!
Rossibaer
 
Ich bin mir nicht ganz sicher wie genau du das mit den "dynamischen View" meinst. Falls einfach nur einen View auf Basis einer Lookup (habt ihr da händisch partitioniert?) erstellen willst währe das dann so etwas:
Code:
set quoted_identifier off
go

declare @sqlstr as varchar(8000)
declare @tbl_name as varchar(255)

if exists (select * from sysobjects where name='ViewName' and xtype='V' ) drop view ViewName

set @sqlstr='
  create view ViewName
  as
'
delcare cur_tbl_name cursor for 
  select TabName from TabIndex

open cur_tbl_name
fetch next from cur_tbl_name into @tbl_name

-- ersten eintrag initialisieren
if @@fetch_status=0
  set @sqlstr=@sqlstr+'select * from '+@tlb_name

fetch next from cur_tbl_name into @tbl_name
while @@fetch_status=0
begin
  set @sqlstr=@slqstr+'
    union all
    select * from '+@tbl_name
  fetch next from cur_tbl_name into @tbl_name  
end

close cur_tbl_name
deallocate cur_tbl_name

print @sqlstr
exec(@sqlstr)

Ist jetzt natürlich nur ins blaue geschrieben (wie ich Fehler hasse :freaky: ).

Gruß
Azdak
 
Zurück
Oben