Ich habe eine gespeicherte Prozedur, die 80 Spalten und 300 Zeilen zurückgibt. Ich möchte eine Auswahl schreiben, die 2 dieser Spalten erhält. Etwas wie
SELECT col1, col2 FROM EXEC MyStoredProc 'param1', 'param2'
Wenn ich die obige Syntax verwendet habe, erhalte ich den Fehler:
"Spaltenname ungültig".
Ich weiß, dass die einfachste Lösung darin besteht, die gespeicherte Prozedur zu ändern, aber ich habe sie nicht geschrieben und kann sie nicht ändern.
Gibt es eine Möglichkeit zu tun, was ich will?
Ich könnte eine temporäre Tabelle erstellen, um die Ergebnisse einzufügen, aber da es 80 Spalten gibt, müsste ich eine temporäre Tabelle mit 80 Spalten erstellen, um 2 Spalten zu erhalten. Ich wollte vermeiden, alle zurückgegebenen Spalten aufzuspüren.
Ich habe versucht,
WITH SprocResults AS ....
wie von Mark vorgeschlagen zu verwenden, aber ich habe 2 Fehler erhaltenFalsche Syntax in der Nähe des Schlüsselworts 'EXEC'.
Falsche Syntax in der Nähe ')'.Ich habe versucht, eine Tabellenvariable zu deklarieren, und habe den folgenden Fehler erhalten
Einfügefehler: Der Spaltenname oder die Anzahl der angegebenen Werte stimmen nicht mit der Tabellendefinition überein
Wenn ich es versuche,
SELECT * FROM EXEC MyStoredProc 'param1', 'param2'
erhalte ich den Fehler:Falsche Syntax in der Nähe des Schlüsselworts 'exec'.
quelle
EXEC
ist kein MySQL-Schlüsselwort (das MySQL-Äquivalent sind vorbereitete Anweisungen ). Obwohl ich die Antwort für MySQL wissen möchte, zielen die folgenden Antworten auf T-SQL ab. Retagging.Antworten:
Können Sie die Abfrage aufteilen? Fügen Sie die gespeicherten Proc-Ergebnisse in eine Tabellenvariable oder eine temporäre Tabelle ein. Wählen Sie dann die 2 Spalten aus der Tabellenvariablen aus.
quelle
Hier ist ein Link zu einem ziemlich guten Dokument, in dem die verschiedenen Möglichkeiten zur Lösung Ihres Problems erläutert werden (obwohl viele davon nicht verwendet werden können, da Sie die vorhandene gespeicherte Prozedur nicht ändern können.)
So teilen Sie Daten zwischen gespeicherten Prozeduren
Gulzars Antwort wird funktionieren (es ist im obigen Link dokumentiert), aber das Schreiben wird mühsam sein (Sie müssen alle 80 Spaltennamen in Ihrer @ tablevar (col1, ...) - Anweisung angeben. Und in Zukunft Wenn dem Schema eine Spalte hinzugefügt oder die Ausgabe geändert wird, muss sie in Ihrem Code aktualisiert werden, da sonst ein Fehler auftritt.
quelle
Quelle:
http://stevesmithblog.com/blog/select-from-a-stored-procedure/
quelle
Das funktioniert bei mir: (dh ich brauche nur 2 Spalten der 30+, die von zurückgegeben wurden
sp_help_job
)Bevor dies funktionieren würde, musste ich Folgendes ausführen:
.... um die
sys.servers
Tabelle zu aktualisieren . (dh die Verwendung einer Selbstreferenz in OPENQUERY scheint standardmäßig deaktiviert zu sein.)Für meine einfache Anforderung stieß ich auf keines der Probleme, die im Abschnitt OPENQUERY von Lances ausgezeichnetem Link beschrieben wurden.
Rossini, wenn Sie diese Eingabeparameter dynamisch einstellen müssen, wird die Verwendung von OPENQUERY etwas umständlicher:
Ich bin mir nicht sicher, welche Unterschiede (falls vorhanden) zwischen der Verwendung
sp_serveroption
zumsys.servers
direkten Aktualisieren der vorhandenen Selbstreferenz und der Verwendungsp_addlinkedserver
(wie in Lances Link beschrieben) zum Erstellen eines Duplikats / Alias bestehen.Anmerkung 1: Ich bevorzuge OPENQUERY gegenüber OPENROWSET, da OPENQUERY die Definition der Verbindungszeichenfolge innerhalb des Prozesses nicht erfordert.
Anmerkung 2: Nachdem ich das alles gesagt habe: Normalerweise würde ich nur INSERT ... EXEC verwenden :) Ja, es ist 10 Minuten mehr Zeit für die Eingabe, aber wenn ich helfen kann, ziehe ich es vor, nicht herumzuspielen mit:
(a) Anführungszeichen innerhalb von Anführungszeichen innerhalb Anführungszeichen und
(b) Sys-Tabellen und / oder hinterhältige selbstreferenzierende Verbindungsserver-Setups (dh für diese muss ich meinen Fall unseren allmächtigen Datenbankadministratoren vorlegen :)
In diesem Fall konnte ich jedoch kein INSERT ... EXEC-Konstrukt verwenden, da
sp_help_job
bereits eines verwendet wird. ("Eine INSERT EXEC-Anweisung kann nicht verschachtelt werden.")quelle
Um dies zu erreichen, erstellen Sie zunächst ein "
#test_table
Gefällt mir" :Führen Sie nun die Prozedur aus und geben Sie den Wert ein in
#test_table
:Jetzt holen Sie den Wert von
#test_table
:quelle
Wenn Sie Ihre gespeicherte Prozedur ändern können, können Sie die erforderlichen Spaltendefinitionen einfach als Parameter festlegen und eine automatisch erstellte temporäre Tabelle verwenden:
In diesem Fall müssen Sie eine temporäre Tabelle nicht manuell erstellen - sie wird automatisch erstellt. Hoffe das hilft.
quelle
Es kann hilfreich sein zu wissen, warum dies so schwierig ist. Eine gespeicherte Prozedur kann nur Text zurückgeben ('Text' drucken) oder mehrere Tabellen zurückgeben oder überhaupt keine Tabellen zurückgeben.
So etwas
SELECT * FROM (exec sp_tables) Table1
wird nicht funktionierenquelle
(Angenommen, SQL Server)
Die einzige Möglichkeit, mit den Ergebnissen einer in T-SQL gespeicherten Prozedur zu arbeiten, ist die Verwendung der
INSERT INTO ... EXEC
Syntax. Das gibt Ihnen die Möglichkeit, in eine temporäre Tabelle oder eine Tabellenvariable einzufügen und von dort aus die benötigten Daten auszuwählen.quelle
Ein schneller Hack wäre, einen neuen Parameter hinzuzufügen
'@Column_Name'
und die aufrufende Funktion den abzurufenden Spaltennamen definieren zu lassen. Im Rückgabeteil Ihres sproc hätten Sie if / else-Anweisungen und geben nur die angegebene Spalte zurück, oder wenn leer - geben Sie alle zurück.quelle
Wenn Sie dies zur manuellen Validierung der Daten tun, können Sie dies mit LINQPad tun.
Erstellen Sie in LinqPad eine Verbindung zur Datenbank und erstellen Sie dann C # -Anweisungen ähnlich den folgenden:
Referenz http://www.global-webnet.net/blogengine/post/2008/09/10/LINQPAD-Using-Stored-Procedures-Accessing-a-DataSet.aspx
quelle
Für SQL Server finde ich, dass dies gut funktioniert:
Erstellen Sie eine temporäre Tabelle (oder eine permanente Tabelle, die eigentlich keine Rolle spielt) und fügen Sie eine Anweisung in die gespeicherte Prozedur ein. Die Ergebnismenge des SP sollte mit den Spalten in Ihrer Tabelle übereinstimmen, da sonst eine Fehlermeldung angezeigt wird.
Hier ist ein Beispiel:
Das ist es!
quelle
Wie in der Frage erwähnt, ist es schwierig, die temporäre Tabelle mit 80 Spalten zu definieren, bevor die gespeicherte Prozedur ausgeführt wird.
Umgekehrt besteht die Tabelle darin, die Tabelle basierend auf der Ergebnismenge der gespeicherten Prozedur zu füllen.
Wenn Sie eine Fehlermeldung erhalten, müssen Sie verteilte Ad-hoc-Abfragen aktivieren, indem Sie die folgende Abfrage ausführen.
Um
sp_configure
mit beiden Parametern eine Konfigurationsoption zu ändern oder dieRECONFIGURE
Anweisung auszuführen , muss Ihnen die Berechtigung aufALTER SETTINGS
Serverebene erteilt werdenJetzt können Sie Ihre spezifischen Spalten aus der generierten Tabelle auswählen
quelle
Versuche dies
quelle
Ich weiß, dass die Ausführung von sp und das Einfügen in eine temporäre Tabelle oder Tabellenvariable eine Option wäre, aber ich denke nicht, dass dies Ihre Anforderung ist. Gemäß Ihrer Anforderung sollte die folgende Abfrageanweisung funktionieren:
Wenn Sie eine vertrauenswürdige Verbindung haben, verwenden Sie die folgende Abfrageanweisung:
Wenn beim Ausführen der obigen Anweisung eine Fehlermeldung angezeigt wird, führen Sie einfach die folgende Anweisung aus:
Ich hoffe, dies wird jemandem helfen, der mit einem ähnlichen Problem konfrontiert ist. Wenn jemand versuchen würde, eine temporäre Tabelle oder Tabellenvariable zu verwenden, die wie folgt aussehen sollte, aber in diesem Szenario sollten Sie wissen, wie viele Spalten Ihr SP zurückgibt, sollten Sie so viele Spalten in einer temporären Tabelle oder Tabellenvariablen erstellen:
quelle
Für alle, die über SQL 2012 oder höher verfügen, konnte ich dies mit gespeicherten Prozeduren erreichen, die nicht dynamisch sind und jedes Mal die gleichen Spalten ausgeben.
Die allgemeine Idee ist, dass ich die dynamische Abfrage erstelle, um die temporäre Tabelle zu erstellen, in sie einzufügen, aus ihr auszuwählen, sie zu löschen und sie auszuführen, nachdem alles generiert wurde. Ich generiere die temporäre Tabelle dynamisch, indem ich zuerst Spaltennamen und -typen aus der gespeicherten Prozedur abrufe .
Hinweis: Es gibt viel bessere, universellere Lösungen, die mit weniger Codezeilen funktionieren, wenn Sie bereit / in der Lage sind, den SP zu aktualisieren oder die Konfiguration und Verwendung zu ändern
OPENROWSET
. Verwenden Sie das Folgende, wenn Sie keinen anderen Weg haben.quelle
Der einfachste Weg, wenn Sie dies nur einmal benötigen:
Exportieren Sie im Import- und Export-Assistenten nach Excel und importieren Sie dieses Excel in eine Tabelle.
quelle
Erstellen Sie eine dynamische Ansicht und erhalten Sie ein Ergebnis daraus .......
quelle
Ich würde den ursprünglichen SP ausschneiden und einfügen und alle Spalten außer den gewünschten 2 löschen. Oder. Ich würde die Ergebnismenge zurückbringen, sie einem richtigen Geschäftsobjekt zuordnen und dann die beiden Spalten LINQ.
quelle