PDA

Vollständige Version anzeigen : dynamisch Spalten in Tabellen hinzu fügen


Susi
03.04.2002, 14:16
Hallo,
ich hab´ da eine Frage:
ich habe über SQL eine Auswertung zu machen, bei der Werte über mehrere Jahre gegenüber gestellt werden sollen.
Das ganze würde ich gerne über eine Schleife laufen lassen, in der - dem im aktuellen Schleifenlauf auszuwertenden Jahr entsprechend - dynamisch die Spalten innerhalb einer Tabelle hinzu gefügt werden.
Soll also ungefähr so aussehen (dann kann sich´s auch jeder vorstellen):
1999 2000 2001 2002 ...
Wert 1
Wert 2
Wert 3
.
.
.

Ich habe schon verschiedene Sachen ausprobiert, aber bei Zufügen der neuen Spalte innerhalb der Schleife knallt´s jedes Mal.
Die Datenbank kann mit dem in der Add-Anweisung angegebenen column_name nichts anfangen. Vermutlich muss ich da mit einem einer Tabellenspalte entsprechenden Variablentyp arbeiten.
Aber ich habe keine Ahnung, wie ich das hinkriegen soll.

Kann mir jemand weiter helfen?
Danke,
Susi

Das hier ist der Programmcode zum Aufbau der Tabelle, mit dem ich bislang gescheitert bin:

/*
Tabelle löschen, falls da
*/
IF EXISTS (SELECT * from sysobjects
WHERE id = object_id(N'[master].[dbo].[TabErgebnis]') AND
OBJECTPROPERTY(id, N'IsUserTable') = 1)
DROP Table [master].[dbo].[TabErgebnis]

declare
@dtBeginn datetime,
@dtEnde datetime

select @dtBeginn = convert(datetime, '01.01.2000 00:00:00', 104)
select @dtEnde = convert(datetime, '31.12.2000 23:59:59', 104)

/*
Ergebnistabelle anlegen
*/
select ' ' = replicate(' ', 200) into TabErgebnis

while not convert(varchar, datepart(yyyy, @dtEnde)) > '2004'
begin

/*
Spalte zufügen :-(
*/
alter table TabErgebnis add
convert(varchar, datepart(yyyy, @dtEnde)) varchar(20)

/* wenn das mit dem Zufügen der Spalte klappen würde, würde ich an
dieser Stelle gern die in der Tabelle enthaltenen Zeilen insofern
ändern, als dass ich die neu eingefügte Spalte mit einem Wert
versorge
DAMIT HAB´ ICH ABER WAHRSCHEINLICH DAS NÄCHSTE PROBLEM
*/

/*
Auswertungsjahr hochzählen
*/
select @dtBeginn = dateadd(yyyy, 1, @dtBeginn)
select @dtEnde = dateadd(yyyy, 1, @dtEnde)
end

select * from TabErgebnis

/*
Tabelle wieder löschen
*/
IF EXISTS (SELECT * from sysobjects
WHERE id = object_id(N'[master].[dbo].[TabErgebnis]') AND
OBJECTPROPERTY(id, N'IsUserTable') = 1)
DROP Table [master].[dbo].[TabErgebnis]

Joachim Hofmann
05.04.2002, 17:25
Vielleicht ist der Spaltenname kein gültiger?

Versuche, zu debuggen, indem Du den Namen vorher mal ausgibst:


.......

/*
Ergebnistabelle anlegen
*/
select ' ' = replicate(' ', 200) into TabErgebnis

while not convert(varchar, datepart(yyyy, @dtEnde)) > '2004'
begin

/* debug test */
SELECT 'Test: ' + convert(varchar, datepart(yyyy, @dtEnde)) > '2004'

.......

Susi
08.04.2002, 14:41
Hallo Joachim,
vielen Dank schon mal für deine Antwort.

Leider hilft mir dein Vorschlag nicht weiter.
Der Debug-Versuch "SELECT 'Test: ' + convert(varchar, datepart(yyyy, @dtEnde))" gibt in jedem Schleifenlauf die richtige Jahreszahl aus - das funktioniert.
Wenn ich aber dann versuche, mit dem "convert ..." den Spaltennamen im Add-Befehl anzugeben, bekomme ich jedes Mal den Syntax-Fehler "Server: Nachr.-Nr. 156, Schweregrad 15, Status 1, Zeile 31
Incorrect syntax near the keyword 'convert'.".

Ich hab´s auch schon mit einer Variablen probiert...

declare @Spaltenname varchar(4)

select @Spaltenname = convert(varchar, datepart(yyyy, @dtEnde))
alter table TabErgebnis add
@Spaltenname varchar(20)

...hat aber auch nicht geklappt.

Ich denke, dass der Fehler darin besteht, dass ich versuche, den Spaltennamen mit einem Charakter anzugeben.
Wahrscheinlich müsste hinter dem "add" eine Variable von einem Typ, der einer Tabellenspalte entspricht, angegeben werden. Und einer solchen Variablen müsste als Bezeichnung die Jahreszahl aus dem jeweils aktuellen Schleifenlauf mitgegeben werden können.
In der SQL-Online-Dokumentation steht leider bei der Syntax-Beschreibung nur, dass nach dem "add" der Name der Spalte anzugeben ist.
Wenn man diesen explizit angibt, klappt ja auch alles wunderbar.

Aber es kann doch nicht sein, dass ich die Spalten einer Tabelle über SQL nicht auch variabel aufbauen kann.
Ich müsste ja jedes Mal, wenn ich so ein Problem habe, ein anderes Programm drum herum stricken, das die SQL-Anweisungen entsprechend zusammen setzt und über eine Datenbank-Schnittstelle ausführt.
Das muss doch irgendwie direkt über SQL gehen.

Susi

Joachim Hofmann
11.04.2002, 10:34
Hallo,

ich glaube man muß EXECUTE benutzen.
Hier ein Auszug aus der Hilfe.


C. Verwenden von EXECUTE ‘tsql_string‚ mit einer Variablen
Dieses Beispiel zeigt, wie EXECUTE dynamisch erstellte Zeichenfolgen behandelt, die Variablen enthalten. Das Beispiel erzeugt einen Cursor (tables_cursor), der eine Liste aller benutzerdefinierten Tabellen (type = U) enthält.

Anmerkung Dieses Beispiel wird nur zu Illustrationszwecken gezeigt.


<FONT color=#804040>SELECT</FONT> name <FONT color=#6a5acd>FROM</FONT> sysobjects <FONT color=#6a5acd>WHERE</FONT> type = <FONT color=#ff00ff>'U'</FONT>
OPEN tables_cursor
DECLARE @tablename <SPAN style="background-color: #ffdead"><FONT color=#0000ff>sysname</FONT></SPAN>
FETCH NEXT <FONT color=#6a5acd>FROM</FONT> tables_cursor <FONT color=#6a5acd>INTO</FONT> @tablename
<FONT color=#804040>WHILE</FONT> (@@FETCH_STATUS <> <FONT color=#ff00ff>-1</FONT>)
<FONT color=#804040>BEGIN</FONT>
<SPAN style="background-color: #ffdead"><FONT color=#008000>/* A @@FETCH_STATUS of -2 means that the row has been deleted.</FONT></SPAN>
<SPAN style="background-color: #ffdead"><FONT color=#008000> There is no need to test for this because this loop drops all</FONT></SPAN>
<SPAN style="background-color: #ffdead"><FONT color=#008000> user-defined tables. */</FONT></SPAN>.
EXEC (<FONT color=#ff00ff>'DROP TABLE '</FONT> + @tablename)
FETCH NEXT <FONT color=#6a5acd>FROM</FONT> tables_cursor <FONT color=#6a5acd>INTO</FONT> @tablename
<FONT color=#804040>END</FONT>
PRINT <FONT color=#ff00ff>'All user-defined tables have been dropped from the database.'</FONT>
DEALLOCATE tables_cursor