[REQ] SQL: USE @variable funktioniert nicht
3mind 03.01.2008 - 12:26 1815 12
3mind
mimimi
|
hallo leute, ich möchte ein script erstellen (vorzugsweise t-sql / sql) mit welchem die datensätze und tabellen zweier datenbanken abgeglichen werden können. am liebsten hätte ich das folgendermaßen: eingabe der namen von master-datenbank und der neuen datenbank und das script durchläuft jede tabelle der masterDB und schaut ob diese existiert in der neuen DB (wenn nicht --> copy der kompletten tabelle inklusive daten, wenn ja --> fehlende datensätze kopieren, keine datensätze löschen). wenn tabellen nur in der neuen jedoch nicht in der masterDB existieren sollen diese nicht gelöscht werden. ich hab jetzt schonmal begonnen mir das zu überlegen, bin mir aber nichtmal sicher ob es möglich ist eine procedure zu schreiben die unterschiedliche datenbanken verwendet? das codefragment zeigt meinen ersten ansatz: /* synchronizeDB.sql mk | 03.01.08
-- --
Synchronisiert eine Datenbank mit einer Master-Datenbank. Dabei werden fehlende
Datensätze und Tabellen hinzugefügt, jedoch keine bestehenden Daten oder
Tabellen gelöscht!
last update : 03.01.08
===============================================================================
*/
CREATE PROCEDURE Synchronize(@masterDB VARCHAR(200), @newDB VARCHAR(200))
AS
DECLARE @command varchar(500)
DECLARE @tblName varchar(200)
DECLARE cur CURSOR FOR
-- Wenn es sich um Tabellen handelt, dann xtype='u', bei Views xtype='v'
SELECT [name]
FROM sysobjects
WHERE xtype = 'u' AND [name] LIKE 't%'
OPEN cur
FETCH NEXT FROM cur INTO @tblName
WHILE @@fetch_status = 0 BEGIN
/*
IF (EXISTS (SELECT * FROM @newDB.@tblName))
ELSE
SELECT *
INTO @newDB.@tblName
FROM @masterDB.@tblName
SET @command = 'drop View ' + @tblName
EXECUTE(@command)
*/
FETCH NEXT FROM cur INTO @tblName
END -- WHILE
CLOSE cur
DEALLOCATE cur
-- PROCEDURE
jegliche vorschläge und tipps sind mehr als willkommen! tia
Bearbeitet von 3mind am 22.04.2008, 10:14
|
3mind
mimimi
|
hm, keiner auch nur irgend einen ansatz?
|
Triple-X
Addicted
|
Zwischen Datenbanken kannst du mit USE wechseln also: USE [DB Name]
Am besten wechselst du nach dem Öffnen des Cursors auf die neue Datenbank.
Was dir vielleicht auch noch hilft: "SELECT * FROM sys.tables" liefert eine Auflistung der vorhandenen Tabellen in einer Datenbank.
|
3mind
mimimi
|
danke Triple-X ... das mit USE hab ich mittlerweile schon umgesetzt, und auch erste fortschritte erzielt. leider stellt mich besonders der ansatz der dynamischen sql-programmierung immer wieder vor schwierigkeiten, die besonders zeitaufwändig sind (meist ist es eh nur eine syntax-gschicht). soweit funktionierts jetzt schonmal: /* synchronizeDB.sql mk | 03.01.08
-- --
Synchronisiert eine Datenbank mit einer Master-Datenbank. Dabei werden fehlende
Datensätze und Tabellen hinzugefügt, jedoch keine bestehenden Daten oder
Tabellen gelöscht!
last update : 04.01.08
===============================================================================
*/
DECLARE @masterDB NVARCHAR(200)
DECLARE @syncDB NVARCHAR(200)
DECLARE @sql1 NVARCHAR(4000)
DECLARE @sql2 NVARCHAR(4000)
DECLARE @tblName NVARCHAR(200)
SET @masterDB = 'masterDB'
SET @syncDB = 'syncDB'
USE masterDB;
DECLARE cur CURSOR FOR
-- Wenn es sich um User-Tabellen handelt, dann xtype='u'
SELECT [name]
FROM sysobjects
WHERE xtype = 'U'
USE syncDB;
OPEN cur
FETCH NEXT FROM cur INTO @tblName
WHILE @@fetch_status = 0
BEGIN
IF NOT EXISTS (SELECT * FROM sysobjects WHERE type = 'U' AND NAME LIKE @tblName)
-- copy the table and all of its contents
BEGIN
SET @sql1 = (N'SELECT * INTO ' + @tblName + ' FROM ' + @masterDB+ '..' + @tblName);
EXEC(@sql1);
END
ELSE
-- copy only missing values, don't overwrite anything
BEGIN
PRINT 'bla';
END
FETCH NEXT FROM cur INTO @tblName
END -- WHILE
CLOSE cur
DEALLOCATE cur
schön wärs ja wenn man auch für das USE statement eine variable verwenden kann, funktioniert aber leider nicht
|
ica
hmm
|
ich kenn deine anforderungen zwar nicht, aber schön schaut diese lösung nicht aus. wieso nicht eine slave datenbank einrichten? wird der sql server wohl unterstützen.
vorallem die konsistenz kann dir da schnell verloren gehen bei relationen.
|
3mind
mimimi
|
also, zum einen: ms sql server 2000 wird eingesetzt, keine ahnung ob da was mit slave datenbank zu machen ist (hab ich auch noch nichts zu gelesen bisher).
zum anderen, der voraussichtliche einsatz: man fährt mit masterDB + script zum kunden und gleicht dessen datenbank ab. daher ist die konsistenz kein relevanter argumentations-grund (weil eh nie beide auf einer maschine verwendet werden sollen).
|
3mind
mimimi
|
zwar konnten nicht alle meine fragen beantwortet werden, aber setz es dennoch mal auf solved.
|
3mind
mimimi
|
ich hab den thread mal wieder aufgemacht.
es wär mir nach wie vor ein großes anliegen eine möglichkeit zu finden wie man einen DB-wechsel im script (USE ...) mit einer variablen welche den namen der DB enthält durchführen kann. (also bspw. USE @otherDB )
vielleicht hat ja doch wer die zeit und das wissen mir zu helfen, wäre spitze!
\\edit: threadtitel geändert
Bearbeitet von 3mind am 22.04.2008, 10:14
|
DKCH
...
|
du kannst use zwar in einem exec-aufruf verwenden, es gilt aber nur für genau diesen aufruf. SET @sql1 = (N'USE '+@db_name+' SELECT * INTO ' + @tblName + ' FROM ' + @masterDB+ '..' + @tblName);
EXEC(@sql1);
würd funktionieren...
|
prayerslayer
Oar. Mh.
|
wennst dort premiummember bist/wen kennst ders is, hier stellt wer die gleiche frage. hier steht eine lösung for free, hth. USE darfst nämlich net verwenden in procedures/functions/triggers, wie du eh schon gemerkt hast //damnit, DKCH!!
|
prayerslayer
Oar. Mh.
|
whoho, kann es sein, dass in einer stored procedure DROP TABLE @table;
auch nicht geht?
|
DKCH
...
|
jo, ich glaub für ddl-statements brauchst immer exec()
|
prayerslayer
Oar. Mh.
|
tatsächlich... drop procedure schluckt er aber. ts... thx!
|