Erstellen Sie eine parametrisierte ANSICHT in SQL Server 2008

72

Können wir in SQL Server 2008 eine parametrisierte VIEW erstellen?

Oder eine andere Alternative dafür?

Sreekumar P.
quelle

Antworten:

124

Versuchen Sie, eine Inline-Tabellenwertfunktion zu erstellen. Beispiel:

CREATE FUNCTION dbo.fxnExample (@Parameter1 INTEGER)
RETURNS TABLE
AS
RETURN
(
    SELECT Field1, Field2
    FROM SomeTable
    WHERE Field3 = @Parameter1
)

-- Then call like this, just as if it's a table/view just with a parameter
SELECT * FROM dbo.fxnExample(1)

Wenn Sie den Ausführungsplan für SELECT anzeigen, wird die Funktion überhaupt nicht erwähnt und es werden nur die zugrunde liegenden Tabellen angezeigt, die abgefragt werden. Dies ist gut, da beim Generieren eines Ausführungsplans für die Abfrage Statistiken zu den zugrunde liegenden Tabellen verwendet werden.

Zu vermeiden wäre eine Tabellenfunktion mit mehreren Anweisungen, da die zugrunde liegenden Tabellenstatistiken nicht verwendet werden und aufgrund eines schlechten Ausführungsplans zu einer schlechten Leistung führen können.
Beispiel, was zu vermeiden ist :

CREATE FUNCTION dbo.fxnExample (@Parameter1 INTEGER)
    RETURNS @Results TABLE(Field1 VARCHAR(10), Field2 VARCHAR(10))
AS
BEGIN
    INSERT @Results
    SELECT Field1, Field2
    FROM SomeTable
    WHERE Field3 = @Parameter1

    RETURN
END

Subtil anders, aber mit möglicherweise großen Leistungsunterschieden, wenn die Funktion in einer Abfrage verwendet wird.

AdaTheDev
quelle
Dies war eine hilfreiche Antwort für mich. Danke AdaTheDev!
TWood
2
Es gibt ein Problem, wenn ein Anruf zwischen Verbindungsservern erforderlich ist. Funktionen mit Tabellenwerten sind nicht zulässig.
Timofey
7
Das Beispiel, was zu vermeiden ist, ist sehr, sehr wichtig. Ich habe nur eine Änderung vorgenommen, um meine Funktion an das erste Beispiel anzupassen (weg von dem "was zu vermeiden ist"), und ich habe eine enorme Leistungsverbesserung erhalten.
Jeff Widmer
1
Wird eine UNION im "guten" Beispiel sie in die Kategorie "vermeiden" verschieben?
G. Stoynev
7

Tatsächlich gibt es einen Trick:

create view view_test as

select
  * 
from 
  table 
where id = (select convert(int, convert(binary(4), context_info)) from master.dbo.sysprocesses
where
spid = @@spid)

... in SQL-Abfrage:

set context_info 2
select * from view_test

wird das gleiche sein mit

select * from table where id = 2

Die Verwendung von udf ist jedoch akzeptabler

heximal
quelle
17
Ich würde ernsthaft weinen , viele, viele weinen , Eimer voll. Schlaflose Nächte ...
Adriaan Stander
17
Keine Respektlosigkeit, aber dies ist ein gutes Beispiel für den Unterschied zwischen dem, was Sie tun können und dem, was Sie tun sollten (oder nicht).
Gjvdkamp
7
Ich bestehe nicht auf dieser Lösung. und ich habe es selbst nie in mssql benutzt. Ich habe gerade erwähnt, dass es theoretisch möglich ist
heximal
Upvoted für den interessanten Hack. Nicht, dass dies verwendet werden sollte.
Chris Cudmore
2

Wie Astander erwähnt hat, können Sie dies mit einem UDF tun. Bei großen Mengen unter Verwendung einer skalaren Funktion (als oppoosed auf eine Inline-Tabellenfunktion) wird die Leistung als die Funktion Gestank Zeile- für -Zeile ausgewertet wird. Alternativ können Sie dieselben Ergebnisse über eine gespeicherte Prozedur verfügbar machen, die eine feste Abfrage mit Platzhaltern ausführt, die Ihre Parameterwerte ersetzt.

( Hier ist ein etwas veralteter, aber immer noch relevanter Artikel zur zeilenweisen Verarbeitung für skalare UDFs.)

Bearbeiten: Kommentare zu. Verschlechterung der Leistung angepasst, um deutlich zu machen, dass dies für skalare UDFs gilt.

Davek
quelle
3
Wenn Sie die UDF als Inline-Tabellenwertfunktion schreiben, gibt es keinen Grund, warum die Leistung überhaupt schlecht sein sollte. Wenn Sie sprechen sind skalare Funktionen dann ja, wird die Funktion für jede Zeile ausgewertet werden
AdaTheDev
Entschuldigung für das Versehen - Sie haben ganz recht. Ich werde meine Antwort bearbeiten, um das klar zu machen.
Davek
-1

Nein. Sie können UDF verwenden, in dem Sie Parameter übergeben können.

Pankaj Agarwal
quelle
17
Hast du eine der anderen Antworten gelesen? Könnte dies bereits erwähnt worden sein?
Adriaan Stander