SQL Statement mit variablen Tabellennamen (from @Tabellenvariable)

Also, ein Statement wie „select from @Tabellenvariable“ , egal ob als SELECT, Insert oder Update, geht nicht.
Nach langer Recherche bin ich auf die Lösung gekommen. Dynamisches SQL. Darüber wurde viel geschrieben und einen guten Artikel darüber findet man hier.

Sehr komplex und doch so einfach. Eigentlich bildet man in einer SP (gespeicherten Prozedur) eine Variable ’nvarchar(max)‘. Diese Variable wird soweit bereitgestellt, sodass diese das gesamte Statement enthält. Nachdem diese gesetzt ist, führen Sie das Statement mit der integrierten Prozedur ’sp_executesql‘ aus Ref:-> sp_executesql (Transact-SQL).

Die MAXimale Variablenausprägung nvarchar(max) habe ich gewählt, damit der Name nicht gekürzt wird. Obwohl (max) etwas groß gewählt ist (max) = 4000 Zeichen Ref:-> nchar und nvarchar (Transact-SQL) und darf natürlich an Ihre Gegebenheit angepasst werden.

Hier ein einfaches Beispiel:

declare @Tabellenname as nvarchar(max)
declare @Statement as nvarchar(max)

set @Tabellenname = '[an_ITdb].[dbo].[TBL_RevisionsProtokoll]'
Set @Statement = 'Select * from ' + @Tabellenname
execute sp_executesql @Statement

Im Beispiel werden unter 1 + 2 zwei Variablen vom Datentyp nvarchar Ref-> MS SQL Datentypen deklariert. Danach werden die Variablen mit SET gefüllt und der integrierten Prozedur unter zur Hilfenahme des Ausführungsbefehls ausgeführt. Das selbe Ergebnis würde dieses Statement liefern:

Select * from [an_ITdb].[dbo].[TBL_RevisionsProtokoll]

Warum das Ganze? Es gibt Gegebenheiten in Tabellenstrukturen, indem man sich gedacht hat, jeden Monat eine neue Tabelle per Code anzulegen. Hintergrund ist meist die Tatsache, das nicht vorausgesehen werden kann, wie groß eine Tabelle letztendlich wird. In solchen Fällen kann ein Tabellensysteme nach Perioden, wie monatlich, angelegt werden. Wenn Ihre Anwendung jetzt auf solche Tabellen trifft, müssen Sie eine Möglichkeit schaffen, diese nach Datum zu durchsuchen. Ein echtes Problem, weil: select from @Tabellenvariable – geht nicht.
Was also tun? Am einfachsten Sie erstellen eine SP (gespeicherte Prozedur) Ref-> Gespeicherte Prozeduren (Datenbankmodul) und ermitteln die Tabellenstruktur, das Datum und bauen das Statement zusammen um es dann per EXECUTE auszuführen.

Hier mal ein Beispiel:

USE [BierDatenbank]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alf Nielsen
-- Create date: 02.03.2015
-- Description:	Liefert die monatliche Rohstoffvereinnahmung aus dem Hostsystem
-- =============================================
Create PROCEDURE [dbo].[SP_Biermenge_perWarengruppe]
        --Deklariert eine INPUT Variable. Warengruppe 866 - Helles Bier
        @Warengruppe int
AS
BEGIN
	SET NOCOUNT ON;
        -- Unsere Tabelle, die wir abfragen möchten, ist nach JAHR - MONAT strukturiert.
        -- Wir müssen diesen Tabellennamen erarbeiten. Dieser sieht so aus:  bm0088_001_201503_ls55. Wobei im Mittelteil das Jahr und der Monat (immer zweistellig) angegeben ist.
	--1. Dynamische Ermittlung des Datums. 
	declare @ResultDate as datetime = getutcdate() --'26.03.2014 00:00:00' TIPP: Gewöhnen Sie sich gleich an, mit der UTC Zeit zu arbeiten, Sie werden es sonst irgendwann später bereuen.
        --2. Monatsvariable zB 03
	declare @Monat as nvarchar(10)
        --3. Stringteile
	declare @Tabellenname as nvarchar(200) = 'bm0088_001_'
	declare @Tabellenname_suffix as nvarchar(20) = '_ls55' 

	--Ermittlung des aktuellen Monats. Wenn Monat 1 - 9 dann muss eine "0" vorangestellt werden. MONTH(datetime) liefert den Monat 1 - 12
	if MONTH (@ResultDate) < 10
	begin
                --@Monat wird mit einer 0 gefüllt. Ergebnis= 03
		set @Monat = '0' + convert(varchar, MONTH (@ResultDate))
	end
	else 
	begin
                --@Monat wird nicht aufgefüllt, da schon zweistellig
		set @Monat = MONTH (@ResultDate)
	end
        --@Tabellenname zusammensetzen aus den oben gewonnenen Ergebnissen
	set @tabellenname = @tabellenname + convert(varchar, year (@ResultDate)) + @monat + @tabellenname_suffix
	--Ergibt = bm0088_001_201503_ls55 - Warum? Weil: @tabellenname = "bm0088_001_"  + convert(varchar, year (@ResultDate)) = "2015" + @monat = "03" + @tabellenname_suffix = "_ls55"
        --Somit haben wir den Tabellennamen für den Monat März 03 und das Jahr 2015

	--Variable für das gesamte Statement deklarieren
        declare @TempTableStückl as nvarchar(Max);
	
	Set @TempTableStückl = 'Select * from ' + @Tabellenname + ' where spalte_Warengruppe = ' + @Warengruppe
	execute sp_executesql @TempTableStückl

END

Fertig.
Stand: 26.03.2015

Schreibe einen Kommentar