Gibt es eine Möglichkeit, ein Erstellungsskript ausschließlich in T-SQL aus einer vorhandenen Tabelle zu generieren (dh ohne Verwendung von SMO, da T-SQL keinen Zugriff auf SMO hat)? Angenommen, eine gespeicherte Prozedur empfängt einen Tabellennamen und gibt eine Zeichenfolge zurück, die das Erstellungsskript für die angegebene Tabelle enthält.
Lassen Sie mich nun die Situation beschreiben, mit der ich konfrontiert bin, da es einen anderen Weg geben kann, dies zu tun. Ich habe eine Instanz mit mehreren Dutzend Datenbanken. Diese Datenbanken haben alle dasselbe Schema, dieselben Tabellen, denselben Index usw. Sie wurden im Rahmen einer Softwareinstallation eines Drittanbieters erstellt. Ich muss eine Möglichkeit haben, mit ihnen zu arbeiten, damit ich Daten von ihnen ad-hoc aggregieren kann. Nette Leute bei dba.se haben mir hier schon geholfen Wie erstelle ich einen Trigger in einer anderen Datenbank?
Derzeit muss ich einen Weg finden, eine Auswahl aus einer Tabelle in allen Datenbanken zu treffen. Ich habe alle Datenbanknamen in einer Tabelle mit dem Namen aufgezeichnet Databasees
und das folgende Skript geschrieben, um eine select-Anweisung für alle von ihnen auszuführen:
IF OBJECT_ID('tempdb..#tmp') IS NOT NULL
DROP TABLE #tmp
select * into #tmp from Database1.dbo.Table1 where 1=0
DECLARE @statement nvarchar(max) =
N'insert into #tmp select * from Table1 where Column1=0 and Cloumn2 =1'
DECLARE @LastDatabaseID INT
SET @LastDatabaseID = 0
DECLARE @DatabaseNameToHandle varchar(60)
DECLARE @DatabaseIDToHandle int
SELECT TOP 1 @DatabaseNameToHandle = Name,
@DatabaseIDToHandle = Database_Ref_No
FROM Databasees
WHERE Database_Ref_No > @LastDatabaseID
ORDER BY Database_Ref_No
WHILE @DatabaseIDToHandle IS NOT NULL
BEGIN
DECLARE @sql NVARCHAR(MAX) = QUOTENAME(@DatabaseNameToHandle) + '.dbo.sp_executesql'
EXEC @sql @statement
SET @LastDatabaseID = @DatabaseIDToHandle
SET @DatabaseIDToHandle = NULL
SELECT TOP 1 @DatabaseNameToHandle = Name,
@DatabaseIDToHandle = Database_Ref_No
FROM Databasees
WHERE Database_Ref_No > @LastDatabaseID
ORDER BY Database_Ref_No
END
select * from #tmp
DROP TABLE #tmp
Das obige Skript schlägt jedoch mit der folgenden Meldung fehl:
Ein expliziter Wert für die Identitätsspalte in der Tabelle '#tmp' kann nur angegeben werden, wenn eine Spaltenliste verwendet wird und IDENTITY_INSERT auf ON gesetzt ist.
Dies hinzufügen:
SET IDENTITY_INSERT #tmp ON
hilft nicht, da ich die Spaltenliste nicht spezifizieren und generisch halten kann.
In SQL gibt es keine Möglichkeit, die Identität für eine bestimmte Tabelle auszuschalten. Sie können nur eine Spalte löschen und eine Spalte hinzufügen, was natürlich die Spaltenreihenfolge ändert. Und wenn sich die Spaltenreihenfolge ändert, müssen Sie erneut die Spaltenliste angeben, die je nach der von Ihnen abgefragten Tabelle unterschiedlich ist.
Daher überlegte ich, ob ich den Scrip create table in meinem T-SQL-Code abrufen und mit Zeichenfolgenmanipulationsausdrücken bearbeiten könnte, um die Identitätsspalte zu entfernen und dem Resultset auch eine Spalte für den Datenbanknamen hinzuzufügen .
Kann sich jemand einen relativ einfachen Weg vorstellen, um das zu erreichen, was ich will?