Ich habe folgenden Code:
Using cmd As SqlCommand = Connection.CreateCommand
cmd.CommandText = "UPDATE someTable SET Value = @Value"
cmd.CommandText &= " WHERE Id = @Id"
cmd.Parameters.AddWithValue("@Id", 1234)
cmd.Parameters.AddWithValue("@Value", "myValue")
cmd.ExecuteNonQuery
End Using
Ich frage mich, ob es eine Möglichkeit gibt, die endgültige SQL-Anweisung als String abzurufen, die folgendermaßen aussehen sollte:
UPDATE someTable SET Value = "myValue" WHERE Id = 1234
Wenn sich jemand fragt, warum ich das tun würde:
- zum Protokollieren von (fehlgeschlagenen) Anweisungen
- für die Möglichkeit, es zu Testzwecken zu kopieren und in den Enterprise Manager einzufügen
Antworten:
Obwohl es nicht perfekt ist, habe ich mich für TSQL entschieden - könnte leicht für andere Geschmacksrichtungen optimiert werden ... Wenn nichts anderes, gibt es Ihnen einen Ausgangspunkt für Ihre eigenen Verbesserungen :)
Dies führt einen OK-Job für Datentypen und Ausgabeparameter usw. aus, ähnlich wie bei der Verwendung von "Gespeicherte Prozedur ausführen" in SSMS. Wir haben meistens SPs verwendet, damit der Befehl "text" keine Parameter usw. Berücksichtigt
Dies erzeugt eine Ausgabe in diese Richtung ...
quelle
ToBooleanOrDefault
hier sehen: Frage # 3244850Für die Protokollierung gibt es leider keinen besseren Weg, dies zu tun, als den String selbst zu erstellen:
quelle
query = Regex.Replace(query, @"\b" + p.ParameterName + @"\b", p.Value.ToString());
die Parameter in der Zeichenfolge zu ersetzen. Dies wird das "ganze Wort" ersetzen. Dies ist jedoch möglicherweise keine universelle Lösung, da \ b eine Position zwischen einem Wortzeichen und einem Nichtwortzeichen markiert.p.ParameterName + @"\b"
Wenn Ihre Parameternamen also mit @ beginnen, sollten Sie den Parameter in der Abfragezeichenfolge ersetzen.Sie können nicht, weil es kein SQL generiert.
Die parametrisierte Abfrage (die in
CommandText
) wird als Äquivalent einer vorbereiteten Anweisung an den SQL Server gesendet. Wenn Sie den Befehl ausführen, werden die Parameter und der Abfragetext separat behandelt. Zu keinem Zeitpunkt wird eine vollständige SQL-Zeichenfolge generiert.Mit SQL Profiler können Sie einen Blick hinter die Kulissen werfen.
quelle
Ich brauchte einen ähnlichen Befehl wie String String Transformator, um eine ausführlichere Protokollierung zu ermöglichen, also habe ich diesen geschrieben. Es wird der Text erzeugt, der zum erneuten Ausführen des Befehls in einer neuen Sitzung erforderlich ist, einschließlich Ausgabeparametern und strukturierten Parametern. Es ist leicht getestet, aber Vorbehalt Emptor.
Beispiel:
Wird herstellen:
Implementierung:
quelle
N
Präfix aufzunehmen.Ich hatte auch dieses Problem, bei dem einige parametrisierte Abfragen oder SPs mir eine SqlException gaben (meistens wurden die Zeichenfolgen oder Binärdaten abgeschnitten), und die Anweisungen waren schwer zu debuggen (soweit ich weiß, gibt es derzeit keine Unterstützung für SQL-Profiler SQL Azure)
Ich sehe hier viel ähnlichen Code in Reaktionen. Am Ende habe ich meine Lösung für die zukünftige Verwendung in ein SQL-Library-Projekt gestellt.
Der Generator ist hier verfügbar: https://github.com/jeroenpot/SqlHelper/blob/master/Source/Mirabeau.MsSql.Library/SqlGenerator.cs
Es unterstützt sowohl CommandType.Text als auch CommandType.StoredProcedure
Und wenn Sie das Nuget-Paket installieren , können Sie es mit folgender Anweisung generieren:
quelle
Wenn Sie SQL Server verwenden, können Sie den SQL Server Profiler (falls vorhanden) verwenden, um die tatsächlich ausgeführte Befehlszeichenfolge anzuzeigen. Das wäre nützlich zum Testen / Einfügen von Testzwecken, aber leider nicht zum Protokollieren.
quelle
Späte Antwort, ich weiß, aber ich wollte das auch, damit ich die SQL protokollieren kann. Das Folgende ist kurz und entspricht meinen Bedürfnissen.
Im Folgenden wird SQL erstellt, das Sie in SSMS kopieren / einfügen können (es ersetzt die Parameter ordnungsgemäß durch die Werte). Sie können weitere Typen hinzufügen, aber dies entspricht allem, was ich in diesem Fall verwende.
Jetzt kann ich SQL protokollieren, bevor ich es ausführe:
quelle
Profiler ist zweifellos die beste Option.
Aufgrund der Schritte zum Vorbereiten und Ausführen müssen Sie möglicherweise eine Reihe von Anweisungen aus dem Profiler kopieren.
quelle
Ich hatte genau die gleiche Frage und nachdem ich diese Antworten gelesen hatte, entschied ich fälschlicherweise, dass es nicht möglich war, die genaue resultierende Abfrage zu erhalten. Ich lag falsch.
Lösung: Öffnen Sie
Activity Monitor
inSQL Server Management Studio
verengen sich die Prozesse Abschnitt auf die Login - Benutzernamen, Datenbank- oder Anwendungsnamen , dass Ihre Anwendung in der Verbindungszeichenfolge verwendet. Wenn der Aufruf der Datenbankaktualisierung erfolgtActivity Monitor
. Wenn Sie den Vorgang sehen, klicken Sie mit der rechten Maustaste darauf undView Details
.Beachten Sie, dass dies möglicherweise keine praktikable Option für eine ausgelastete Datenbank ist. Mit diesen Schritten sollten Sie das Ergebnis jedoch erheblich eingrenzen können.
quelle
Verwendet einen Teil von Flappers Code für meine Lösung, der die gesamte SQL-Zeichenfolge einschließlich der Parameterwerte zurückgibt, die in MS SQL SMS ausgeführt werden sollen.
quelle
Meine Lösung:
quelle
Ich habe diese Methode für mich geschrieben. Ich benutze einen Teil von Bruno Ratnieks Code. Vielleicht ist es für jemanden nützlich.
quelle
Wenn nur überprüft werden soll, wie ein Parameter in der Ergebnisabfrage formatiert ist, können die meisten DBMS Literale aus dem Nichts abfragen. So:
Auf diese Weise können Sie sehen, ob Anführungszeichen verdoppelt werden usw.
quelle
Dies ist, was ich verwende, um Parameterlisten für eine gespeicherte Prozedur in der Debug-Konsole auszugeben:
Dadurch wird eine ähnliche Konsolenausgabe generiert:
Ich platziere diesen Code direkt unter jeder Prozedur, die ich debuggen möchte, und ähnelt einer SQL-Profiler-Sitzung, jedoch in C #.
quelle
Geänderte Version der Antwort von Kon, da sie nur teilweise mit ähnlich benannten Parametern funktioniert. Die Kehrseite der Verwendung der Funktion "String ersetzen". Davon abgesehen gebe ich ihm die volle Anerkennung für die Lösung.
quelle
Diese Lösung funktioniert gerade für mich. Vielleicht ist es für jemanden nützlich. Bitte entschuldigen Sie die Redundanz.
quelle
Wie bei @pkExec und @Alok erwähnt, funktioniert die Verwendung von Ersetzen in 100% der Fälle nicht. Dies ist die Lösung, die ich in unserem DAL verwendet habe und die RegExp verwendet, um nur "ganze Wörter abzugleichen" und die Datentypen korrekt zu formatieren. Somit kann das generierte SQL direkt in MySQL Workbench (oder SQLSMS usw.) getestet werden :)
(Ersetzen Sie die Funktion MySQLHelper.EscapeString () gemäß dem verwendeten DBMS.)
Beispiel:
Wird generiert:
quelle
Die SQL-Befehlsabfragen werden mit exec sp_executesql ausgeführt. Hier ist eine andere Möglichkeit, die Anweisung als Zeichenfolge abzurufen (SqlCommand-Erweiterungsmethode):
quelle
musste auch nicht gespeicherte Prozeduren abdecken, daher habe ich die CommandAsSql-Bibliothek (siehe Kommentare unter @ Flappers Antwort oben) mit dieser Logik erweitert:
Die Pull-Anforderung lautet: https://github.com/jphellemons/CommandAsSql/pull/3/commits/527d696dc6055c5bcf858b9700b83dc863f04896
Die Regex-Idee basierte auf den obigen Kommentaren von @ stambikk und EvZ sowie dem Abschnitt "Update:" von https://stackoverflow.com/a/2544661/903783 , in dem "negative Look- Behind -Behauptung" erwähnt wird. Die Verwendung von \ B anstelle von \ b für die Erkennung von Wortgrenzen zu Beginn des regulären Ausdrucks liegt daran, dass der p.parameterName immer mit einem "@" beginnt, das kein Wortzeichen ist.
Beachten Sie, dass ParameterValueForSQL () eine Erweiterungsmethode ist, die in der CommandAsSql-Bibliothek definiert ist, um Probleme wie Zeichenfolgenparameterwerte in einfachen Anführungszeichen usw. zu behandeln.
quelle
Wenn Sie den Befehlstext konvertieren:
Jetzt können Sie den Nicht-Parameter-Befehlstext wie folgt abrufen:
und das Ergebnis ist "UPDATE someTable SET Value = 'myValue' WHERE Id = 1234" ohne Parameter mehr
quelle
Der Code von Kon wurde erweitert , um das Debuggen einer gespeicherten Prozedur zu erleichtern:
In meinem ersten Testfall wurde Folgendes generiert:
Sie müssen wahrscheinlich weitere bedingte Typzuweisungen "..is ..." hinzufügen, z. B. für Datum und Uhrzeit.
quelle
Einzeiler:
quelle
Vom Parameterbefehl zum Nichtparameterbefehl können Sie diesen ändern
Zu
quelle