2009-12-11 13 views
5

Ho alcune stored procedure complesse che estraggono dati da altri database utilizzando server collegati. Questi dati vengono inseriti in tabelle temporanee che vengono uniti in una query di selezione per l'output. Le procedure funzionano bene, ma in Visual Studio se provo ad aggiungere la procedura memorizzata a un set di dati utilizzando il designer, ottengo l'errore nome oggetto non valido #tmp o qualsiasi altra cosa venga chiamata la prima tabella temporanea. Non è in grado di recuperare lo schema del database. È lo stesso per l'utilizzo e sqldatasource in ASP.NET.Recupera lo schema dei campi in Visual Studio della stored procedure che utilizza le tabelle temporanee

La procedura è ancora utilizzabile ma devo aggiungere manualmente tutte le colonne che deve essere inviata al datatable. Questo sarà un problema da fare manualmente e presumo che abbia a che fare con il modo in cui visual studio raccoglie i campi di output dalla stored procedure, non sembra che lo esegua nel modo normale. C'è un modo per correggere questo perché ho un sacco di questi da fare e non voglio dover aggiungere tutte le colonne manualmente, che richiede molto tempo ed è soggetto a errori.

+0

C'è un motivo per cui non è possibile utilizzare una funzione valore di tabella anziché una stored procedure? – Wilhelm

+0

Sì, non è possibile utilizzare SQL dinamico o openquery in una funzione per quanto ne so. Correggimi se sbaglio – PeteT

+0

Ho risposto alla mia stessa domanda dopo molte più ricerche. C'è una bizzarra soluzione. – PeteT

risposta

12

Dopo googling per un po 'ho trovato una soluzione bizzarra mettere:

IF 1=0 BEGIN 
SET FMTONLY OFF 
END 

All'inizio della stored procedure consente al progettista di ottenere in modo corretto le informazioni sullo schema. Questo codice ovviamente non funziona mai, ma risolve il problema. FMTONLY è correlato solo alla restituzione dei metadati relativi a una stored procedure. Sto usando sql server 2005.

+1

ATTENZIONE! Tenere presente che quando si esegue questa operazione, la stored procedure verrà effettivamente eseguita e impegnata in modo completo ogni volta che il designer di Visual Studio la controlla. Se si dispone di eventuali istruzioni di aggiornamento/cancellazione/inserimento nel proprio proc, verranno eseguite. Utilizzalo solo nelle procedure che restituiscono solo i dati. Altrimenti, questa è una scoperta eccellente! –

0

Il motivo per cui non è possibile leggere i metadati è perché si dispone di una tabella #Temp e non è possibile trovare la tabella temporanea. Si può cercare di ottenere intorno ad esso definendo i metadati utilizzando una query TOP 0

SELECT TOP 0 
    CONVERT (NULL, VarChar (30)) AS Column1, 
    CONVERT (NULL, INTEGER) AS Column2, 
    CONVERT (NULL, DECIMAL (9, 2)) AS Column3, 
    CONVERT (NULL, VarChar (55)) AS Column4 

UNION 

SELECT * 
FROM #MyTempTable 
+0

Semes come quello richiederanno quasi il tempo, non vedo perché visual studio non può ottenere i metadati eseguendo la query normalmente poiché, ad esempio, il report Crystal può farlo senza problemi. – PeteT

0

Il motivo non è possibile ottenere i metadati qui è perché potrebbe dipendere da dati. Per esempio.

If Exists(Select 1 From Table Where Column1 = 7) 
    Select Col1, Col2 From Table2 
Else 
    Select Col3, Col4, Col5 From Table2 

non avrei mai scritto una stored procedure che ha un diverso numero di colonne a seconda dei dati, ma è possibile fare. Solo per un momento, supponiamo che tu abbia una procedura memorizzata come questa. Quale lista di colonne dovrebbe essere restituita?

+0

Sì, lo capisco e non vorrei nemmeno scriverne uno in cui restituirebbe potenzialmente un numero diverso di colonne. Ma perché non recupera solo le colonne per le variabili che ho specificato. – PeteT

+0

Perché potrebbe ancora non essere deterministico. Considerare inoltre che una stored procedure potrebbe non restituire recordset, un recordset o anche più recordset. È anche possibile utilizzare le funzioni di numeri casuali in modo che ogni chiamata restituisca colonne diverse. –

+0

Sì, ma è usato solo per il designer, lo sviluppatore sa quali colonne devono esistere, alla fine è solo più veloce per metterle dentro in base ai valori che gli vengono dati per il processo memorizzato. Un esempio è il report di cristallo che prende i valori che gli vengono dati ed estrae l'ultimo datatable che viene fornito da una stored procedure. Non importa il fatto che potrebbero non esistere in fase di esecuzione, poiché è sempre il caso in quanto è possibile modificare facilmente qualsiasi query sql. – PeteT

2

Questo funziona per me:

SET FMTONLY OFF

Non so perché qualcuno ha messo in IF 1 = 0 in altri post? Penso che fosse solo per dimostrare che quando FMTONLY è ON tutte le condizioni nelle istruzioni IF/ELSE sono eseguite!

FMTONLY viene in genere attivato da applicazioni come SSRS e Visual Studio durante l'aggiornamento delle informazioni sullo schema per un file stp. Con FMTONLY su nessuna istruzione vengono eseguiti solo i nomi delle colonne vengono restituiti. Il problema è che poiché non vengono eseguite istruzioni, la tabella temporanea non viene creata e pertanto le colonne restituite da qualsiasi istruzione select sulla tabella temporanea sono sconosciute.

L'impostazione FMTONLY ON farà sì che lo stp funzioni completamente. Se si dispone di istruzioni di inserimento/aggiornamento/eliminazione nel proprio stp, verranno eseguite, quindi acquisire lo stato di FMTONLY prima di disattivarlo e adottare le misure appropriate per evitare aggiornamenti.

È possibile determinare se FMTONLY è acceso controllando se 1 = 0. In caso affermativo FMTONLY è acceso e si può semplicemente eseguire una semplice selezione delle colonne normalmente restituite dallo stp.

Problemi correlati