2013-06-15 10 views
7

Ho provato ad aggiornare una procedura memorizzata che ha funzionato correttamente senza la necessità di utilizzare sp_executesql. Ora desidero avere il nome della tabella come parametro poiché ho un numero di tabelle con la stessa struttura e non voglio creare nuove stored procedure per ognuna di esse.Procedura memorizzata con nome tabella come parametro tra gli altri

Il problema che ho è che questa versione sembra richiedere tutti i parametri, mentre la precedente ha accettato un numero qualsiasi di parametri. Ad esempio, se rimuovo tutti i parametri WHERE e ho solo il parametro @TableName, funziona correttamente. Ho provato a cercare un esempio, ma non riesco a trovare nulla di simile. Tutti gli esempi di analisi del nome della tabella hanno solo quel parametro.

CREATE PROCEDURE cafgTenantNamesTEST2 
    @TableName sysname, 
    @Square nvarchar(100) = null, 
    @Location nvarchar(100) = null, 
    @Name nvarchar(100) = null, 
    @NormalizedName nvarchar(100) = null, 
    @SharedLand int = 0, 
    @FieldNumber int = 0, 
    @Description nvarchar(255) = null, 
    @Dwelling nvarchar(100) = null 
AS 
BEGIN 
    DECLARE @sql AS NVARCHAR(MAX) 
    SET @sql = 'SELECT * FROM [' + @TableName + ']' + 
    'WHERE ([Square] LIKE ''' + @Square + ''' OR ''' + @Square + ''' IS NULL)' + 
    'AND ([Location] = ''' + @Location + ''' OR ''' + @Location + ''' IS NULL)' + 
    ... 
    ... 
--PRINT @sql 
EXEC sp_executesql @sql 
END 

Suggerimenti per favore.

+0

Controllare il valore di @sql e assicurarsi che possa essere eseguito. Puoi costruire una stringa sql codificando il nome della tabella e far funzionare la clausola Where? – JeffO

+3

Prova ad aggiungere uno spazio prima di 'WHERE' e' AND' che stai concatenando senza spazi vuoti. – HABO

risposta

10

Suggerimento 1: Utilizzare QUOTENAME() per gestire l'escaping corretto del nome della tabella.

Suggerimento 2: Si sta inserendo il valore del parametro in @sql. Non farlo. Invece dovresti usare pameterized lo sql.

Suggerimento 3: eliminare la logica OR da condizionale costruzione clausola WHERE della query.

CREATE PROCEDURE cafgTenantNamesTEST2 
    @TableName sysname, 
    @Square nvarchar(100) = null, 
    @Location nvarchar(100) = null, 
    @Name nvarchar(100) = null, 
    @NormalizedName nvarchar(100) = null, 
    @SharedLand int = 0, 
    @FieldNumber int = 0, 
    @Description nvarchar(255) = null, 
    @Dwelling nvarchar(100) = null 
AS 
BEGIN 
    DECLARE @sql AS NVARCHAR(MAX) 
    SET @sql = N'SELECT * FROM ' + QUOTENAME(@TableName) + 
    ' WHERE 1=1 ' 
    IF @Square IS NOT NULL 
     SET @sql = @sql + ' AND ([Square] LIKE @Square)' -- still patameterized 
    IF @Location IS NOT NULL 
     SET @sql = @sql + N' AND ([Location] = @Loc)' 
    ... 
    ... 
--PRINT @sql 
EXEC sp_executesql @sql, N'@Square nvarchar(100), @Loc nvarchar(100)...', @[email protected], @[email protected] -- the param names can be the same or different, sp_executesql has it's own scope. 
END 

Sp_executesql può eseguire sql con parametri oltre a sql semplice. È la stored procedure di sistema sottostante utilizzata dalle librerie client per eseguire codice parametrizzato. Ad esempio, System.Data.SqlClient.SqlCommand chiamerà sp_executesql se sono stati aggiunti parametri. È atipico in quanto accetta un numero variabile di parametri. I documenti msdn su sp_executesql forniscono alcune buone informazioni, ma non sono chiare. Acquisire attività in SQL profiler è il modo più semplice per vedere sp_executesql in azione.

+0

Brillante. Grazie per questo @StrayCatDBA. Ho usato sql semplice per anni, ma ho appena iniziato a usare sp e sto ancora lottando con loro. Ci lavorerò domani, visto che sono legato oggi. Posso supporre con questo metodo che posso includere nessuno o nessun numero di parametri quando si chiama questo proc? –

+0

Mi spiace, potrebbe anche spiegare la linea EXEC? Cioè perché le dichiarazioni –

+0

Ha funzionato, grazie. Tranne che non riesco ancora a vedere cosa fa la riga di exec come se includessi i parametri in esso ottengo un errore: _Procedure si aspetta il parametro '@parameters' di tipo 'ntext/nchar/nvarchar'_. –

Problemi correlati