2013-06-15 17 views
7

Ich habe versucht, eine gespeicherte Prozedur zu aktualisieren, die ohne die Verwendung von sp_executesql funktionierte. Ich möchte jetzt den Tabellennamen als Parameter haben, da ich mehrere Tabellen mit der gleichen Struktur habe und nicht für jede von ihnen neue gespeicherte Prozeduren erstellen möchte.Gespeicherte Prozedur mit Tabellenname als Parameter

Das Problem, das ich habe, ist, dass diese Version alle Parameter erfordert, während die vorherige eine beliebige Anzahl von Parametern akzeptiert hat. Zum Beispiel, wenn ich alle WHERE-Parameter entfernen und nur den Parameter @TableName haben, funktioniert es gut. Ich habe versucht, nach einem Beispiel zu suchen, aber ich kann nichts dergleichen finden. Alle Beispiele zum Analysieren des Tabellennamens haben nur diesen Parameter.

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 

Vorschläge bitte.

+0

Überprüfen Sie den Wert von @sql und stellen Sie sicher, dass es ausgeführt werden kann. Können Sie eine SQL-Zeichenfolge erstellen, indem Sie den Tabellennamen fest codieren und die WHERE-Klausel verwenden? – JeffO

+3

Versuchen Sie, ein Leerzeichen vor dem 'WHERE' und dem' AND', das Sie verketten, ohne Leerzeichen hinzuzufügen. – HABO

Antwort

10

Vorschlag 1: Verwenden Sie QUOTENAME(), um das korrekte Entkommen des Tabellennamens zu behandeln.

Vorschlag 2: Sie fügen den Wert des Parameters in @sql ein. Tu das nicht. Stattdessen sollten Sie pameterized die SQL verwenden.

Vorschlag 3: Beseitigen Sie die OR-Logik, indem Sie die WHERE-Klausel der Abfrage bedingt erstellen.

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 kann parameterized sql zusätzlich zu plain sql ausführen. Es ist die zugrunde liegende gespeicherte Systemprozedur, die von Clientbibliotheken zum Ausführen von parametrisiertem Code verwendet wird. Beispielsweise wird System.Data.SqlClient.SqlCommand sp_executesql aufrufen, wenn Sie Parameter hinzugefügt haben. Es ist untypisch, da es eine variable Anzahl von Parametern akzeptiert. Die msdn docs on sp_executesql bieten einige gute Informationen, ist aber nicht klar. Das Erfassen von Aktivitäten in SQL Profiler ist der einfachste Weg, um sp_executesql in Aktion zu sehen.

+0

Brilliant. Danke für diese @StrayCatDBA. Ich habe seit Jahren geradlinige SQL verwendet, aber ich habe gerade erst begonnen, SPs zu benutzen, und ich kämpfe immer noch mit ihnen. Ich werde morgen daran arbeiten, da ich heute gefesselt bin. Kann ich mit dieser Methode dann davon ausgehen, dass ich beim Aufruf dieses Proc keine oder beliebig viele Parameter aufnehmen kann? –

+0

Entschuldigung, könnten Sie bitte auch die EXEC-Linie erklären? I.e. warum die Erklärungen. –

+0

Das hat funktioniert, danke. Außer, ich kann immer noch nicht sehen, was die Exec-Zeile tut, als ob ich die Parameter darin einschließe Ich erhalte einen Fehler: _Procedure erwartet den Parameter '@parameters' vom Typ 'ntext/nchar/nvarchar'_. –

Verwandte Themen