2016-03-04 8 views
5

ich einen Tisch haben Users,dynamische SQL in SELECT-Abfrage eingebettet

 
╔════╦═══════╦══════╗ 
║ Id ║ Name ║ Db ║ 
╠════╬═══════╬══════╣ 
║ 1 ║ Peter ║ DB1 ║ 
║ 2 ║ John ║ DB16 ║ 
║ 3 ║ Alex ║ DB23 ║ 
╚════╩═══════╩══════╝ 

und viele Datenbanken, die die gleiche Struktur (gleiche Tabellen, gleiche Verfahren, ...) haben, so haben jede Datenbank eine Tabelle namens Project und dies ist die Struktur der Project Tabelle,

 
╔════╦═════════╦═════════════╗ 
║ Id ║ Request ║ Information ║ 
╠════╬═════════╬═════════════╣ 
║ 1 ║  126 ║ XB1   ║ 
║ 2 ║  126 ║ D6   ║ 
║ 3 ║  202 ║ BM-23  ║ 
╚════╩═════════╩═════════════╝ 

Also, wenn ich eine Datenbank abfragen:

SELECT count(distinct([Request])) as nbrRequests 
    FROM [SRV02].[DB1].[dbo].[Project] 

ich dieses Ergebnis:

 
╔═════════════╗ 
║ NbrRequests ║ 
╠═════════════╣ 
║   2 ║ 
╚═════════════╝ 

Nun, was ich will, ist „link“/„join“ ... Ergebnisse aus der Tabelle Users auf diese Frage, wo die Spalte Db in Users Tabelle ist die Name meiner Datenbank, so kann ich ein Ergebnis wie folgt erhalten:

 
╔════╦═══════╦══════╦═════════════╗ 
║ Id ║ Name ║ Db ║ NbrRequests ║ 
╠════╬═══════╬══════╬═════════════╣ 
║ 1 ║ Peter ║ DB1 ║   2 ║ 
║ 2 ║ John ║ DB16 ║   3 ║ 
║ 3 ║ Alex ║ DB23 ║   6 ║ 
╚════╩═══════╩══════╩═════════════╝ 

Ich versuche mit dynamischem SQL, aber kein Glück.

NB: Jeder Benutzer nur eine Datenbank hat, und eine Datenbank gehört zu nur einem Benutzer, es ist eine Eins-zu-Eins-Beziehung

+1

Gibt es eine Verbindung zwischen die Anforderungs-Tabelle und die Benutzer-Tabelle anders als es auf einer Spezifikation ist Datenbank Und wenn nicht, gibt es mehr als einen Benutzer pro Datenbank, und wenn ja, was wären die Ergebnisse? –

+0

Bitte geben Sie Tabellenrelationen an und wie Sie nbrrequests als 2,3,6 erwarten – TheGameiswar

+0

Db ist die einzige Verbindung, und jeder Benutzer hat nur eine Datenbank, und eine Datenbank gehört nur einem Benutzer. –

Antwort

1

zur Vermeidung der Kombination dieser zwei Antworten https://stackoverflow.com/a/35795690/1460399 und https://stackoverflow.com/a/35795189/1460399, bekam ich diese Lösung:

DECLARE @Query NVARCHAR(MAX)= 'SELECT u.Id, u.Name, u.Db, dbCts.nbrRequests FROM [Users] u INNER JOIN ('; 

DECLARE @QueryLength INT= LEN(@Query); 

SELECT @Query = @Query 
       +CASE WHEN LEN(@Query) > @QueryLength THEN ' UNION ' ELSE '' END 
       +'SELECT '''+Db+''' as db, count(distinct(Request)) as nbrRequests FROM [SRV02].'+Db+'[Project]' 
FROM Users; 

SET @Query = @Query+') dbCts ON u.Db = dbCts.db'; 

EXECUTE (@Query); 
3

Die Art und Weisen Sie tun können, ist es mit einer UNION jede spezifische Datenbank-Tabelle zu zählen und es eine Kennzeichnung für die Datenbank zu geben, wie folgt aus:

SELECT u.Id, u.Name, u.Db, dbCts.nbrRequests 
    FROM [Users] u INNER JOIN 
     (SELECT 'DB1' as db, count(distinct([Request])) as nbrRequests 
     FROM [SRV02].[DB1].[dbo].[Project] 
     UNION 
     SELECT 'DB16', count(distinct([Request])) as nbrRequests 
     FROM [SRV02].[DB16].[dbo].[Project] 
     UNION 
     SELECT 'DB23', count(distinct([Request])) as nbrRequests 
     FROM [SRV02].[DB23].[dbo].[Project] 
    ) dbCts ON u.Db = dbCts.db 

vergessen sie nicht, den Server und das Schema auf die Users Tabelle hinzuzufügen habe ich nicht, weil es keine solche Informationen über Ihre Frage.

Um dies zu tun, muss Ihr verbundener Benutzer außerdem über Berechtigungen für alle Datenbanken verfügen.

+2

Ich denke nicht dass diese Anfrage dynamisch ist, muss ich sie jedes Mal ändern, wenn ich einen Benutzer hinzufüge –

+0

@Hamza_L Es ist nicht dynamisch. Und Sie müssen es jedes Mal ändern, wenn Sie eine Datenbank hinzufügen, da dies keine einfache Aufgabe ist, würde das Hinzufügen von zwei Zeilen in der Abfrage nicht so viel bedeuten. Aber es ist nur ein Ansatz. Fühlen Sie sich frei, die beste Antwort zu wählen :) –

1

Dynamisches SQL kann sehr schwierig sein.

In diesem Beispiel wird die Auswahlabfrage aus der Benutzertabelle erstellt. Die Variable @Query wird für jede Zeile erhöht, die von der Tabelle Users zurückgegeben wird. Jede Zeile gibt eine Abfrage zurück, die die lokale Benutzertabelle mit der Projekttabelle in einer entfernten Datenbank verbindet. Die Ergebnisse jeder Abfrage sind UNIONED zusammen.

Beispiel

Dieses Beispiel QUOTENAME verwendet SQL injection attacks.

+0

Warum gibt es u.Id = p.Id? u.Id ist die ID des Benutzers, und p.id ist die ID des Projekts –

+0

Sorry, ich missverstanden Sie Schema. Ich werde einen Schnitt machen .... –