2016-03-04 15 views
5

Ho una tabella Users,SQL dinamico incorporato nella query di selezione

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

e molti database che hanno la stessa struttura (tabelle stesse, stesse procedure, ...), in modo da tutti i database hanno una tabella denominata Project , e questa è la struttura della tabella Project,

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

Così, quando ho interrogare un database:

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

ottengo questo risultato:

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

Ora, quello che voglio è quello di "link"/"join" ... i risultati dalla tabella Users a questa domanda, in cui la colonna Db in Users tabella è il nome del mio database, quindi posso ottenere un risultato simile al seguente:

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

Sto provando con SQL dinamico, ma senza fortuna.

NB: Ogni utente ha un solo database, e un database appartengono a un solo utente, è uno-a-uno

+1

Esiste un legame tra la tabella delle richieste e la tabella utente diversa da quella su una specifica un database? E se no, c'è più di un utente per database, e se sì quali sarebbero i risultati? –

+0

specificare le relazioni tra tabelle e il modo in cui ci si aspetta nrrequest come 2,3,6 – TheGameiswar

+0

Db è l'unico collegamento e ogni utente ha un solo database e un database appartiene a un solo utente. –

risposta

1

La combinazione di questi 2 risposte https://stackoverflow.com/a/35795690/1460399 e https://stackoverflow.com/a/35795189/1460399, ho ottenuto questa soluzione:

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

Il modo in cui si può fare è con un UNION contando ogni tabella di database specifico e dandogli un'identificazione per il database, in questo modo:

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 

non dimenticare di aggiungere il server e lo schema al tavolo Users non l'ho fatto perché non esiste informazioni alla tua domanda.

Anche per fare questo, l'utente connesso deve disporre dei privilegi su tutti i database.

+2

Non penso che questa richiesta è dinamica, devo cambiarla ogni volta che aggiungo un utente –

+0

@Hamza_L Non è dinamico. E devi cambiarlo ogni volta che aggiungi un Database, dato che questo non è un compito semplice, aggiungere due righe nella query non sarebbe molto. Ma è solo un approccio. Sentiti libero di scegliere la migliore risposta :) –

1

SQL dinamico può essere molto difficile.

Questo esempio crea la query di selezione dalla tabella utenti. La variabile @Query viene incrementata per ogni riga restituita dalla tabella Utenti. Ogni riga restituisce una query che unisce la tabella degli utenti locali alla tabella dei progetti in un db remoto. I risultati di ogni query sono UNIONED insieme.

Esempio

Questo esempio utilizza QUOTENAME per contribuire ad evitare SQL injection attacks.

+0

perché c'è u.Id = p.Id? u.Id è l'id dell'utente, e p.id è l'id del progetto –

+0

Mi dispiace aver frainteso lo schema. Farò una modifica .... –

Problemi correlati