Benutzer mit den meisten Antworten
Datenbankverbindung per Variable steuern (Auslieferung in verschiedene Umgebungen)

Frage
-
Hallo,
ich soll zu einem zugekauften Standardprogramm eine Schnittstelle zu unserer bestehenden Datenhaltung erstellen. Technisch stelle ich dafür auf in "unserer" Datenbank Views zur Verfügung, auf die ich über einen Verbindungsserver von dem neuen Programmserver aus zugreife.
Natürlich gibt es von unserer Datenbank mehrere Instanzen: Entwicklung, Test, Live... und auch das neue Programm hat eine Live-Installation und eine Entwicklungs- und Testinstallation.
Severversion ist jeweils 2016.
Nun hätte ich gerne von Visual Studio folgendes Verhalten:
Wenn ich das Projekt in die Entwicklungsdatenbank veröffentliche, sollte der Verbindungsserver natürlich auch auf die Entwicklungsdatenbank der alten Datenhaltung zeigen. Nach Abschluss der Tests veröffentliche ich auf den Live-Server und der Verbindungsserver "zeigt" auf die Live-Datenbank.
Mein Plan war folgender: In den Pre-Deployment-Skripten setze ich in Abhängikeit vom Ziel der Veröffentlichung die Variablen $(LinkedServer) etc. In den Skripten zur Erstellung konnte ich diese Variablen schon einbauen. Leider erhalte ich im Skript aber bei
:setvar LinkedServer [A1-SQL-Test]
eine Fehlermeldung SQL80001:Incorrect Syntax near :
Ist das also überhaupt der richtige Weg? Und wenn ja, wie bekomme ich ihn zum Laufen?
Vielen Dank schon mal
Wolfgang
Antworten
-
:setvar LinkedServer [A1-SQL-Test]
eine Fehlermeldung SQL80001:Incorrect Syntax near :
Hallo Wolfgang,
diese Fehlermeldung erhält man in SSMS in einem normalen Query Window oder in eigenen Programmen, weil diese Syntax kein echtes T-SQL ist.
Die Art der Variablendeklaration kennt nur das Tool SqlCmd und SSMS, wenn man über Menu "Abfrage" in den SQLCMD-Modus umschaltet, sowie SSDT Datenbankprojekte, hier aber auch nur in den Pre- und Postdeployment Skripten.
Olaf Helper
[ Blog] [ Xing] [ MVP]- Als Antwort markiert AWombl Donnerstag, 16. April 2020 09:42
-
SQL71561: "Sicht: [dbo].[MyView]" enthält einen nicht aufgelösten Verweis auf "Objekt [$(ServerName)].[$(DatabaseName)].[SchemaName].[ViewName]".
Hallo Wolfgang,
4-Part Qualifier, also Verweise auf einen Verbindungsserver, funktionieren in SSDT Datenbankprojekte gar nicht und 3-Part Qualifier funktionieren nur, wenn Du im Projekt einen entsprechenden Datenbankverweis hinzufügst, das gilt auch für die Systemdatenbanken "master" und "msdb".
Olaf Helper
[ Blog] [ Xing] [ MVP]- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Montag, 13. April 2020 07:19
- Als Antwort markiert AWombl Donnerstag, 16. April 2020 09:42
Alle Antworten
-
Der Verbindungsserver ist ja datenbankneutral und stellt nur einen Dienst bereit.
Du kannst aber in der jeweiilgen DB eine View erstellen, die korrekt auf den richtigen Verbindungsserver verweist-.
Der Name der View ist in allen DB's identisch.create view Ziel as (select * from openquery(verbserver, 'select * from mytable'))
Das schöne daran ist auch, dass eine View dieser Art auch Insert/Update/Delete unterstützt.
https://docs.microsoft.com/de-de/sql/t-sql/functions/openquery-transact-sql?view=sql-server-ver15 -
Hallo, Christoph,
danke für den Link und die Hinweise. Habe ich das richtig verstanden, dass ich über den Alias den Namen des Zielservers vereinheitliche, eine Auswahl der Datenbank (Entwicklung und Test liegen auf einem Server) muss über einen zweiten Schritt geschehen?
Danke und Gruß
Wolfgang
-
Eine semantische (und nicht technische) Namenswahl beim Verbindungsserver macht hier natürlich mehr Sinn als mein Konstrukt. Trotzdem schaffe ich es nicht, den Code gleich zu lassen und auf einem Server zwei unterschiedliche Datenbanken anzusteuern (Entwicklung und Test).
Hast Du dafür auch noch einen Tip?
Danke und Gruß
Wolfgang
-
:setvar LinkedServer [A1-SQL-Test]
eine Fehlermeldung SQL80001:Incorrect Syntax near :
Hallo Wolfgang,
diese Fehlermeldung erhält man in SSMS in einem normalen Query Window oder in eigenen Programmen, weil diese Syntax kein echtes T-SQL ist.
Die Art der Variablendeklaration kennt nur das Tool SqlCmd und SSMS, wenn man über Menu "Abfrage" in den SQLCMD-Modus umschaltet, sowie SSDT Datenbankprojekte, hier aber auch nur in den Pre- und Postdeployment Skripten.
Olaf Helper
[ Blog] [ Xing] [ MVP]- Als Antwort markiert AWombl Donnerstag, 16. April 2020 09:42
-
Das hast du (leider) falsch verstanden.
Wenn eine App mit einer DB verknüpft ist, enthält diese normalerweise alle Tabellen und Sichten, die benötigt werden.
Den Unterschied, ob eine Tabelle in der DB liegt oder via Verbindungsserver erreicht wird, braucht die App letztlich nicht zu interessieren.Du richtest also deine 2 Verbindungen via Verbindungsserver ein, also z.B. "DBEcht" und "DBTest".
In der Datenbank "MyDBEcht" erstellst du eine View "ZielTabelle" auf "DBEcht" und in der Datenbank "MyDBTest" eine View "ZielTabelle" auf "DBTest" .Deine App arbeitet letztlich immer mit "Zieltabelle".
Dies lässt sich mit beliebig vielen Echt/Test-DB's durchziehen. -
Hallo Olaf,
danke, das hilft doch schon einmal weiter.
Nun würde ich gerne eine View erzeugen in der Art
CREATE VIEW [dbo].[MyView] AS SELECT * FROM [$(OtherServer)].[$(DatabaseName)].[SchemaName].[ViewName]
Ich habe natürlich die Zieldatenbank als Datenbankverweis angelegt. Allerdings erkennt das System die Variablen ServerName und DatabaseName nicht. Hier hat das System den Wunsch, eine Variable zu verwenden, die genauso heißt, wie die Datenbank bzw. der Server (gut, damit könnte ich leben, ich würde nur gern verstehen, wo und wie diese Variablen angelegt werden).
Aber ich erhalte auch die Fehlermeldung
SQL71561: "Sicht: [dbo].[MyView]" enthält einen nicht aufgelösten Verweis auf "Objekt [$(ServerName)].[$(DatabaseName)].[SchemaName].[ViewName]".
(wie soll dem Interpreter auch klar sein, wie diese Verbindung zustande kommen soll, das kann ja erst funktionieren, wenn die Variablen belegt sind)
/*
Und ich erhalte einen ganzen Haufen Fehlermeldungen von der Sorte
Der Verweis auf externe Elemente der Quelle mit dem Namen 'master.dacpac' konnte nicht aufgelöst werden, da keine derartige Quelle geladen wurde,
sowohl für die master- als auch für die msdb-Datenbank.
Zumindest dieser Teil der Frage hat sich erledigt. Ich weiß, warum das System die Verweise haben will und konnte sie einbinden.
*/
Ist eine solche Verwendung überhaupt möglich (Da Du von den Pre- und Post-Deployment-Skripten schreibst, habe ich Zweifel an der Auflösung dieser Konstrukte in der Definition einer View)
Vielen Dank im Vorfeld schon mal für Deine Zeit und den Input,
Wolfgang
- Bearbeitet AWombl Mittwoch, 8. April 2020 18:38
-
Genau da ist ja das Problem. Ich habe ein Projektfile, das ich gerne auf verschiedene Server und in verschiedene Datenbanken ausliefern möchte. Und in Abhängigkeit vom Ziel der Auslieferung soll sich diese Verbindung automatisch auf den korrekten Gegenpart einstellen.
Mit Deinem Modell müsste ich entweder verschiedene Projektfiles führen, da der Verweis auf MyDBEcht und MyDBTest in der View-Definition hart verdrahtet ist. Und das möchte ich gern vermeiden, um der To-Do-Liste für eine Auslieferung nicht noch einen Punkt hinzuzufügen, der im schlimmsten (Fehler)Fall eine Testinstallation mit der Live-Datenbank verbindet.
Ein semantisch benannter Verbindungsserver, der auf allen Systemen gleich heißt (und der nicht Teil der Projektdatei sein darf, der muss manuell auf jedem Server angelegt sein) bzw. ein Alias lösen das Problem auch nur halb, da ich den Verbindungsserver/Alias auf jedem Server genau einmal einrichten kann. Da müsste ich mir dann für jede zusätzliche Instanz (Test2, SpielwieseFuerEntwicklungsprojekt,...) einen eigenen SQL-Server auf einer eigenen virtuellen Maschine einrichten. Den Aufwand scheue ich auch.
Ich hoffe, ich verstehe Dich (immer noch) falsch...
Danke und Gruß
Wolfgang
-
Ein SQL-Server kann beliebig viele DB's und ebenso beliebig viele Verbindungsserver verwalten (je nach Lizenz).
Es besteht also kein Grund neue Instanzen zu installieren (außer wenn du verschiedene Versionen betreibst).Eine View kann man nicht so dynamisch erstellen wie du es gerne hättest. Die Definition ist ebenso statisch wie eine Tabelle.
Wenn du eine DB auslieferst würde ich ein Programm anbieten, dass den Vorgang
- Erstellen Verbindungsserver
- Erstellen View auf die benötigten Tabellen
für die auszuwählende DB einrichtet.
Dies könnte auch eine Funktion innerhalb deiner App sein (Optionsdialog Schnittstelle aktivieren/deaktivieren).https://docs.microsoft.com/de-de/sql/relational-databases/linked-servers/create-linked-servers-sql-server-database-engine?view=sql-server-ver15#TsqlProcedure
Das sollte doch flexibel genug für einen Kunden sein, dass dieser die DB's benennen kann.
Mit der obigen Syntax für "Create View ..." bist du auf bestimmte Datenbanken beschränkt, die SQL-Server-Syntax unterstützen.
Zur Laufzeit weißt du durch die Existenz der View/s ob die Schnittstelle eingerichtet ist.
Mittels OPENQUERY bist du Datenbankneutral und kannst sogar Excel-/CSV-Dateien einbinden.- Bearbeitet Der Suchende Mittwoch, 8. April 2020 16:22
-
Hallo Wolfgang,
ja das ist richtig. Wenn Du zwei Umgebungen auf dem gleichen Server hast, dann kannst Du mit einem Alias alleine nicht arbeiten.
Einen schönen Tag noch, Christoph - http://www.insidesql.org/blogs/cmu
- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Montag, 13. April 2020 07:19
-
SQL71561: "Sicht: [dbo].[MyView]" enthält einen nicht aufgelösten Verweis auf "Objekt [$(ServerName)].[$(DatabaseName)].[SchemaName].[ViewName]".
Hallo Wolfgang,
4-Part Qualifier, also Verweise auf einen Verbindungsserver, funktionieren in SSDT Datenbankprojekte gar nicht und 3-Part Qualifier funktionieren nur, wenn Du im Projekt einen entsprechenden Datenbankverweis hinzufügst, das gilt auch für die Systemdatenbanken "master" und "msdb".
Olaf Helper
[ Blog] [ Xing] [ MVP]- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Montag, 13. April 2020 07:19
- Als Antwort markiert AWombl Donnerstag, 16. April 2020 09:42