Discussione:
suggerimento per query con database variabile
(troppo vecchio per rispondere)
Olaffo In The Sky With Diamonds
2010-08-10 08:20:06 UTC
Permalink
il mio problema è il seguente.

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à
Luca Menegotto
2010-08-10 09:33:11 UTC
Permalink
Post by Olaffo In The Sky With Diamonds
CREATE PROCEDURE <nomesp1>
SELECT name
FROM sys.databases
WHERE name NOT IN ('master', 'tempdb', 'model', 'msdb');
...
CREATE PROCEDURE <nomesp2>
AS
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
Olaffo In The Sky With Diamonds
2010-08-10 16:21:18 UTC
Permalink
Post by Luca Menegotto
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
Post by Luca Menegotto
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
Luca Menegotto
2010-08-11 06:35:34 UTC
Permalink
Post by Olaffo In The Sky With Diamonds
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).
Post by Olaffo In The Sky With Diamonds
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'...
Post by Olaffo In The Sky With Diamonds
l'unico sistema che mi è venuto in mente è di usare appunto una query
composta, al limite potrei interrogare in questo modo
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
Continua a leggere su narkive:
Loading...