devo verificare che una determinata tabella esista su ogni user database
di un server, e che nella tabella sia presente almeno un record.
per ora ho creato una sp con il codice
CREATE PROCEDURE <nomesp1>
SELECT name
FROM sys.databases
WHERE name NOT IN ('master', 'tempdb', 'model', 'msdb');
ed un'altra che fa
CREATE PROCEDURE <nomesp2>
(@DBName nvarchar(128))
AS
DECLARE @Query varchar(182)
SET @Query = 'SELECT COUNT(*) FROM ' + @DBName + '.[dbo].<nometab>'
-- PRINT @Query
EXECUTE (@Query)
GO
però credo che la sp mappata tramite LINQ restituisca il return value
della sp e non il risultato della select e non capisco bene come fare.
uso SQL Server 2005 (Express) e VS 2008 - .NET Framework 3.5
, preferibilmente vorrei usare LINQ e stored procedures ma potrei anche
aprirmi ad altre possibilità
> CREATE PROCEDURE <nomesp1>
> SELECT name
> FROM sys.databases
> WHERE name NOT IN ('master', 'tempdb', 'model', 'msdb');
> ...
> CREATE PROCEDURE <nomesp2>
> (@DBName nvarchar(128))
> AS
>
> DECLARE @Query varchar(182)
> SET @Query = 'SELECT COUNT(*) FROM ' + @DBName + '.[dbo].<nometab>'
> -- PRINT @Query
> EXECUTE (@Query)
> GO
Due indicazioni.
1) Se stai leggendo uno schema, leggilo fino in fondo, per avere le
info che ti servono; ogni database espone una vista logica sys.tables
che elenca le tabelle di un database; questo ti evita problemi
derivanti dal fatto che una tabella non esista (a parte il fatto che
potresti usare anche il costrutto TRY/CATCH, ma a me piace più guardare
la vista logica).
2) Non sono assolutamente esperto di LINQ, pero' se vuoi restituire un
valore scalare di tipo da una stored procedure (che poi è l'unico tipo
di dato che puoi ritornare) devi fare la tua valutazione nella stored
procedure e poi invocare la direttiva RETURN.
--
Ciao!
Luca
> Due indicazioni.
>
> 1) Se stai leggendo uno schema, leggilo fino in fondo, per avere le
> info che ti servono;
se noti, la prima sp usa la sys.databases, quindi puoi immaginare che
conosca le viste di sistema.
il problema con la seconda sp è che devo fare una query cross-db (ma la
stored che uso dovrebbe essere localizzata su un db soltanto).
cioè dal database 1 io devo interrogare il database 2, 3, e così via
e non è possibile farlo direttamente.
l'unico sistema che mi è venuto in mente è di usare appunto una query
composta, al limite potrei interrogare in questo modo
SET @Query = 'SELECT 0 FROM ' + @DBName + '.dbo.systables'
il che non risolverebbe comunque i miei problemi, che riguardano il
risultato della query e relativo recupero
> 2) Non sono assolutamente esperto di LINQ, pero' se vuoi restituire un
> valore scalare di tipo da una stored procedure (che poi è l'unico tipo
> di dato che puoi ritornare) devi fare la tua valutazione nella stored
> procedure e poi invocare la direttiva RETURN.
sì, ma come? non capisco come fare nel caso in questione, in cui uso
l'istruzione EXECUTE
> se noti, la prima sp usa la sys.databases, quindi puoi immaginare che
> conosca le viste di sistema. il problema con la seconda sp è che
> devo fare una query cross-db (ma la stored che uso dovrebbe essere
> localizzata su un db soltanto).
Io ti ho dato due suggerimenti, non la soluzione... ;-)
Va bene, sono stato cattivello (e tu non hai usato la Forza).
> cioè dal database 1 io devo interrogare il database 2, 3, e così via
> e non è possibile farlo direttamente.
Vero, perche' non esistono le queries parametriche, pero'...
> l'unico sistema che mi è venuto in mente è di usare appunto una query
> composta, al limite potrei interrogare in questo modo
>
> SET @Query = 'SELECT 0 FROM ' + @DBName + '.dbo.systables'
>
> il che non risolverebbe comunque i miei problemi, che riguardano il
> risultato della query e relativo recupero
Se il tuo problema e' il risultato, e in effetti con Exec testuale non
e' possibile recuperarlo, metti il risultato in una tabella temporanea!
Una cosa del genere, insomma:
CREATE #esisteTabella(NomeTabella varchar(255), numeroRighe int)
EXEC('insert into #esisteTabella SELECT name, COUNT(name) FROM ' +
@DBName + '.dbo.systables WHERE name =''' + @nomeDaCercare + ' group by
name')
(in realta' il nome della tabella non serve...)
-- verifico il numero...
DROP TABLE #esisteTabella
Cercando in internet, a suo tempo, avevo trovato anche riferimento a
una stored procedure non documentata (l'ho ritrovata,
sp_MSforeachtable), che semplifica la vita, che pero' non avevo usato
perche', mi sono detto, se non e' documentata qualche motivo ci
sara'... ;-)
--
Ciao!
Luca