Benutzer mit den meisten Antworten
Dynamischer String elegant bauen

Frage
-
Hi,
Gibt es eigentlich einen "schöneren" Weg ein dynamisches SQL zu bauen (für ein Pivot mit unbekannten Werten) so, dass ich Strings nicht quoten muss?
Zum Beispiel
select
bla, substring(bla, 1, 10) = ''test'')
where
bla = ''irgendwas''
Hab da leider nichts gefunden im Stil eins Escape-Characters oder sowas, wie es das glaub auch in C# gibt...
Antworten
-
Nun ja, SQL ist eher eine statische Angelegenheit. Mit dynmaic tut man sich immer mal schwer.
Allerdings kann man eben mit sp_executesql (siehe link und Beispiel im Link) String und sonstige Konstanten als Parameter "... @ParmName ..." verwenden.
Zu beachten ist leider nur, dass Parameter nur da erlaubt sind, wo Konstanten verwendet werden dürfen.
Felder und Tabellen müssen im String zusammengebaut werden.DECLARE @IntVariable int; DECLARE @SQLString nvarchar(500); DECLARE @ParmDefinition nvarchar(500); /* Build the SQL string one time.*/ SET @SQLString = N'SELECT BusinessEntityID, NationalIDNumber, JobTitle, LoginID FROM AdventureWorks2012.HumanResources.Employee WHERE BusinessEntityID = @BusinessEntityID'; SET @ParmDefinition = N'@BusinessEntityID tinyint'; /* Execute the string with the first parameter value. */ SET @IntVariable = 197; EXECUTE sp_executesql @SQLString, @ParmDefinition, @BusinessEntityID = @IntVariable; /* Execute the same string with the second parameter value. */ SET @IntVariable = 109; EXECUTE sp_executesql @SQLString, @ParmDefinition, @BusinessEntityID = @IntVariable
Wichtig ist halt sowohl die Typdeklaration als auch eben der Parameterwert.
Aber warum eigentlich immer den Server selber bemühen wenn du das auf dem Client mit Parametern doch selber kannst?
Bei sp_executesql, oder auch grundsätzlich bei execute, ist die Anzahl der Parameter ja nicht variabel, da man hier alles hart kodieren muss.Also verlege die Aufgabe des SQL-bauens in den Client, da kannst du
a) den SQL so dynamisch gestalten wie nötig
b) Parameter mit "?" oder je nach Unterstützung auch mit "@ParmName" definierenBeim Ausführen gibt man die Parameter in einer eignen Liste an (ParameterCollection) und die ganze Arie mit Typanpassung, Hochkommaverdoppelung, DatumZeit-Formaten usw. übernimmt der Treiber selber.
- Als Antwort markiert darkchanter Freitag, 3. Mai 2019 14:36
Alle Antworten
-
In welcher Sprache?
I.d.R. kann man mit Command-Objekten und Parametern arbeiten (was i.Ü. absolut zu empfehlen ist), Beispiel .Net:
MyCommand.CommandText = "Select ... from MyTable where bla = ?";
oder
MyCommand.CommandText = "Select ... from MyTable where bla = @Param1";Für jeden Parameter sind dann Parameterobjekte zu erstellen.
Zur Ausführungszeit füllt man die Parameter und lässt das CommandObjekt seine Arbeit tun.
Wieder bei .Net:myreader = MyCommand.ExecuteReader();
- Bearbeitet Der Suchende Freitag, 3. Mai 2019 09:33
-
Hi,
ich denke mal, Du kommst dann nicht drumrum, eben nicht direkt mit dynamischem T-SQL zu arbeiten, da es da außer Parametern nichts gibt, was Du nehmen könntest.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport -
Das mit den Parametern ist schon mal eine Hilfe. Mich nerven halt noch ein bisschen die Literale. Somit vor allem der Umstand, dass ich das SQL-Statement nicht direkt benutzen kann, sondern die vielen Extra-Appostrophs einfügen muss.
Bsp:
select
irgendwas, nochwas + ' (' + dasHier + ')' as bla
where das = 'dies'
Wär halt schön gewesen, wenn hier hier mit einem Escape-Zeichne den SQL-String hätte einbetten können.
Hintergrund: Für dynamische Pivots kenne ich keine andere Möglichkeit, als den String zu bauen mit der Werteliste. So fand ich das auch auf diversen Web-Seiten. Staune auch, dass es keine $Values oder sowas gibt wie beim Merge-Statement.
-
Nun ja, SQL ist eher eine statische Angelegenheit. Mit dynmaic tut man sich immer mal schwer.
Allerdings kann man eben mit sp_executesql (siehe link und Beispiel im Link) String und sonstige Konstanten als Parameter "... @ParmName ..." verwenden.
Zu beachten ist leider nur, dass Parameter nur da erlaubt sind, wo Konstanten verwendet werden dürfen.
Felder und Tabellen müssen im String zusammengebaut werden.DECLARE @IntVariable int; DECLARE @SQLString nvarchar(500); DECLARE @ParmDefinition nvarchar(500); /* Build the SQL string one time.*/ SET @SQLString = N'SELECT BusinessEntityID, NationalIDNumber, JobTitle, LoginID FROM AdventureWorks2012.HumanResources.Employee WHERE BusinessEntityID = @BusinessEntityID'; SET @ParmDefinition = N'@BusinessEntityID tinyint'; /* Execute the string with the first parameter value. */ SET @IntVariable = 197; EXECUTE sp_executesql @SQLString, @ParmDefinition, @BusinessEntityID = @IntVariable; /* Execute the same string with the second parameter value. */ SET @IntVariable = 109; EXECUTE sp_executesql @SQLString, @ParmDefinition, @BusinessEntityID = @IntVariable
Wichtig ist halt sowohl die Typdeklaration als auch eben der Parameterwert.
Aber warum eigentlich immer den Server selber bemühen wenn du das auf dem Client mit Parametern doch selber kannst?
Bei sp_executesql, oder auch grundsätzlich bei execute, ist die Anzahl der Parameter ja nicht variabel, da man hier alles hart kodieren muss.Also verlege die Aufgabe des SQL-bauens in den Client, da kannst du
a) den SQL so dynamisch gestalten wie nötig
b) Parameter mit "?" oder je nach Unterstützung auch mit "@ParmName" definierenBeim Ausführen gibt man die Parameter in einer eignen Liste an (ParameterCollection) und die ganze Arie mit Typanpassung, Hochkommaverdoppelung, DatumZeit-Formaten usw. übernimmt der Treiber selber.
- Als Antwort markiert darkchanter Freitag, 3. Mai 2019 14:36