MSSQL Tabellen per Datum anlegen

EuroCent

Klappstuhl 2.0
Guten Morgen zusammen,

ich habe mal eine Frage.
Und zwar möchte ich gerne, für 7 Tage immer 7 Temp Tabellen erzeugen.
Um ggf. einen Rollback auf die Vorhergehenden Tage zustarten.

Aktuell habe Ich folgenden Ansatz genutzt:

SQL:
ALTER PROCEDURE [dbo].[table_BACKUPS]

AS
BEGIN
    SET NOCOUNT ON;

    IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'table_temp_6')
    BEGIN
        DROP TABLE dbo.table_temp_6
    END

    IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'table_temp_5')
    BEGIN
        exec sp_rename 'table_temp_5', 'table_temp_6'
    END

    IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'table_temp_4')
    BEGIN
        exec sp_rename 'table_temp_4', 'table_temp_5'
    END

    IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'table_temp_3')
    BEGIN
        exec sp_rename 'table_temp_3', 'table_temp_4'
    END

    IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'table_temp_2')
    BEGIN
        exec sp_rename 'table_temp_2', 'table_temp_3'
    END

    IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'table_temp')
    BEGIN
        exec sp_rename 'table_temp', 'table_temp_2'
    END

    IF NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'table_temp')
    BEGIN
        SELECT * INTO dbo.table_temp FROM dbo.table_x
    END

END

Allerdings kann Ich diese nicht in eine andere Prozedur verwenden wenn Ich den Result mir ziehen möchte.
Da mir der sp_rename als Funktion einen Strich durch die Rechnung zieht.

Jetzt ist meine Frage, ist es möglich auch ohne sp_rename Backup-Tabellen zu generieren?

Denn Ich verschicke aktuell 2 Mails, einmal die zur Backup und die andere wenn Ich einen Abgleich starte.
 
Lösung
Wenn ich dich richtig verstanden habe:
Wieso überhaupt rename?
Du hast im Vorfeld alle 7 temp-tabellen (wieso heisst eigentlich die "erste" nicht "table_temp_1"?)
Geh doch folgendermassen vor:
1) Truncate table_temp_6
2) SELECT * INTO table_temp_6 FROM table_temp_5
3) TRUNCATE table_temp_5
4) SELECT * INTO table_temp_5 FROM table_temp_4
usw.
Damit "shiftest" du alle Einträge eine Tabelle weiter. Setzt natürlich voraus, dass alle temp-tabellen dieselbe Spaltenstruktur haben (mich irritiert immer das "*" bei solchen Sachen)

Alternative:
eine einzige temp-Tabelle, jedoch mit einem zusätzlichen Feld Zeitstempel
Aircode
DELETE FROM table_temp WHERE Zeitstempel=Heute-7 Tage
INSERT INTO table_temp (Felder......, Zeitstempel)...
Wenn ich dich richtig verstanden habe:
Wieso überhaupt rename?
Du hast im Vorfeld alle 7 temp-tabellen (wieso heisst eigentlich die "erste" nicht "table_temp_1"?)
Geh doch folgendermassen vor:
1) Truncate table_temp_6
2) SELECT * INTO table_temp_6 FROM table_temp_5
3) TRUNCATE table_temp_5
4) SELECT * INTO table_temp_5 FROM table_temp_4
usw.
Damit "shiftest" du alle Einträge eine Tabelle weiter. Setzt natürlich voraus, dass alle temp-tabellen dieselbe Spaltenstruktur haben (mich irritiert immer das "*" bei solchen Sachen)

Alternative:
eine einzige temp-Tabelle, jedoch mit einem zusätzlichen Feld Zeitstempel
Aircode
DELETE FROM table_temp WHERE Zeitstempel=Heute-7 Tage
INSERT INTO table_temp (Felder......, Zeitstempel) VALUES(Werte....., Heute)

EDIT: Gerade ne "spinnerte" Idee gehabt: Was ist mit Triggern? Ich denke da vor allem an BEFORE DELETE-Trigger
How to create a before delete trigger in SQL Server?
 
Zuletzt bearbeitet:
Lösung
Wenn ich dich richtig verstanden habe:
Wieso überhaupt rename?
Du hast im Vorfeld alle 7 temp-tabellen (wieso heisst eigentlich die "erste" nicht "table_temp_1"?)
Geh doch folgendermassen vor:
1) Truncate table_temp_6
2) SELECT * INTO table_temp_6 FROM table_temp_5
3) TRUNCATE table_temp_5
4) SELECT * INTO table_temp_5 FROM table_temp_4
usw.
Damit "shiftest" du alle Einträge eine Tabelle weiter

Alternative:
eine einzige temp-Tabelle, jedoch mit einem zusätzlichen Feld Zeitstempel
Aircode
DELETE FROM table_temp WHERE Zeitstempel=Heute-7 Tage
INSERT INTO table_temp (Felder......, Zeitstempel) VALUES(Werte....., Heute)
Weil am Anfang die temp1 bis 7 ja noch nicht gibt :D

Ich könnte sie anlegen, und dann durch shiften.
Einweiteres Feld anlegen, könnte man auch, da hast Du recht.

Muss Ich mir mal anschauen.
Naja und rename weil mir das angeboten wurde, also Ich nach einer Lösung gesucht habe.

Meine aktuelle Lösung funktioniert ja auch, allerdings nicht zusammen mit einer anderen Prozedur.
Da er danach Warnings wirft und ohne der Systemadmin der DB zu sein, kann Ich das Warning nicht abschalten. :)

Macht ja auch Sinn dass diese auch da ist. Nur in meinen Fall gerade mal nicht :D
Habe da schon verschiedene Ansätze gehabt mit ANSI_WARNINGS und so...

Aber ich versuche mal deinen Ansatz.
Nichts desto trotz, würde Ich gerne noch sofern es welche gibt, Meinungen anhören :D
 
Hast du mein EDIT gesehen?
Wenn das mit Triggern funktioniert, könnte ich mir vorstellen:
Kein Trigger auf Temp6
Trigger auf Temp5
SQL:
CREATE TRIGGER TRG_table_temp_5
ON table_temp_5
FOR DELETE
AS
     DELETE FROM table_temp_6  /*Ich weiss gerade nicht, ob ein TRUNCATE einen DELETE-Trigger auslöst*/
     INSERT INTO table_temp_6 (ID, NAME, AGE, ADDRESS, LAST_UPDATED)
     SELECT ID, NAME, AGE, ADDRESS, LAST_UPDATED
     FROM DELETED  /*Ist die "DELETED"-Table für table_temp_5*/
usw. bis table_temp_1
SQL:
CREATE TRIGGER TRG_table_temp_1
ON table_temp_1
FOR DELETE
AS
     DELETE FROM table_temp_2  /*Ich weiss gerade nicht, ob ein TRUNCATE einen DELETE-Trigger auslöst*/
     INSERT INTO table_temp_2 (ID, NAME, AGE, ADDRESS, LAST_UPDATED)
     SELECT ID, NAME, AGE, ADDRESS, LAST_UPDATED
     FROM DELETED  /*Ist die "DELETED"-Table für table_temp_1*/
Ablauf:
1) Du feuerst ein DELETE FROM table_temp_1 ab.
2) Der Trigger für temp_1 zündet
3) Innerhalb des Triggers feuerst du ein DELETE FROM temp_2 ab
4) Der Trigger für temp_2 zündet
usw.
Wenn der letzte Trigger erreicht ist, müsste es dann wieder rückwärts laufen, um dann die jeweiligen INSERTS auszuführen
Erstellen von geschachtelten Triggern - SQL Server
 
Hast du mein EDIT gesehen?
Wenn das mit Triggern funktioniert, könnte ich mir vorstellen:
Kein Trigger auf Temp6
Trigger auf Temp5
SQL:
CREATE TRIGGER TRG_table_temp_5
ON table_temp_5
FOR DELETE
AS
     DELETE FROM table_temp_6  /*Ich weiss gerade nicht, ob ein TRUNCATE einen DELETE-Trigger auslöst*/
     INSERT INTO table_temp_6 (ID, NAME, AGE, ADDRESS, LAST_UPDATED)
     SELECT ID, NAME, AGE, ADDRESS, LAST_UPDATED
     FROM DELETED  /*Ist die "DELETED"-Table für table_temp_5*/
usw. bis table_temp_1
SQL:
CREATE TRIGGER TRG_table_temp_1
ON table_temp_1
FOR DELETE
AS
     DELETE FROM table_temp_2  /*Ich weiss gerade nicht, ob ein TRUNCATE einen DELETE-Trigger auslöst*/
     INSERT INTO table_temp_2 (ID, NAME, AGE, ADDRESS, LAST_UPDATED)
     SELECT ID, NAME, AGE, ADDRESS, LAST_UPDATED
     FROM DELETED  /*Ist die "DELETED"-Table für table_temp_1*/
Ablauf:
1) Du feuerst ein DELETE FROM table_temp_1 ab.
2) Der Trigger für temp_1 zündet
3) Innerhalb des Triggers feuerst du ein DELETE FROM temp_2 ab
4) Der Trigger für temp_2 zündet
usw.
Wenn der letzte Trigger erreicht ist, müsste es dann wieder rückwärts laufen, um dann die jeweiligen INSERTS auszuführen
Erstellen von geschachtelten Triggern - SQL Server
Habe Ich eben gelesen.

Trigger da hab Ich noch keine Erfahrung, weil dies bisher nicht in meinem Aufgabenfeld essentiell wichtig war, dass Ich das brauche. :)

Was Ich mir auch dachte sei eine FOR LOOP zu generieren.
Allerdings geht es dann scheinbar nicht wenn Ich folgendes Versuche:
SQL:
ALTER PROCEDURE [dbo].[BACKUP_COPY]
AS
BEGIN
    SET NOCOUNT ON;

    declare @countOfBackupTables AS INT = 7
    declare @counter as INT = 1

    WHILE @counter <= @countOfBackupTables
    BEGIN
        IF NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'table_temp_' + @counter)
        BEGIN
            SELECT * INTO dbo.QUOTENAME('table_temp_' + CONVERT(nvarchar, @counter)) FROM dbo.table
        END

        SET @counter = @counter + 1
    END
END

Fehler:
Incorrect syntax near 'table_temp_'.
 
Zeile 11: Musst du nicht @counter zu Text/String casten/konvertieren?
Zeile 13: Quotename kenn ich nicht (bin kein MSSQL-er)

In Zeile 13 machst du nen Convert, in Zeile 11 nicht....

Sind die einzigen zwei Stellen....
 
Zeile 11: Musst du nicht @counter zu Text/String casten/konvertieren?
Zeile 13: Quotename kenn ich nicht (bin kein MSSQL-er)

In Zeile 13 machst du nen Convert, in Zeile 11 nicht....

Sind die einzigen zwei Stellen....
In Zeile 11 ist es nicht notwendig. :)
Leider kenn Ich Quotenname auch nicht wirklich viel mehr :D
Habe Ich aber in einem Beispiel in Google gehen oO :D

Hab aber verschiede Ansätze versucht :(
 
Dann lass das doch mit der Procedure.
Leg die Tabellen einmal an, und shifte dann durch, oder eben meine Alternative (eine Tabelle aber mit Datums-Feld)

EDIT: Hab was gefunden: A table name as a variable
Hast halt wieder ein EXEC drin......
 
Genauso werde Ich es auch machen, muss das noch besprechen mit meinen Kollegen :D

Danke :* :D
Ein letzter Nachtrag zu meiner "Alternative": Dir ist natürlich klar, dass das die flexibelste Lösung ist?
Falls ihr euch mal entscheidet, anstatt "7 Tage aufzubewahren für Rollback" daraus 14 Tage zu machen (oder was auch immer), ist die einzige Änderung der Zeit-Modifikator im DELETE
SQL:
DELETE FROM table_temp WHERE Zeitstempel<=Heute - 7 Tage
INSERT INTO table_temp (Felder......, Zeitstempel) VALUES(Werte....., Heute)
SQL:
DELETE FROM table_temp WHERE Zeitstempel<=Heute - 14 Tage
INSERT INTO table_temp (Felder......, Zeitstempel) VALUES(Werte....., Heute)
 
Zurück