SQL-Scripts per Kommandozeile ausführen
Posted in SQL Server on Februar 10th, 2011 by Andreas Schwarzsqlcmd -S Server -U Benutzer -P Passwort -i "C:\SqlScript.sql"
sqlcmd -S Server -U Benutzer -P Passwort -i "C:\SqlScript.sql"
Der Großteil der Entwickler wird sich bei Datenbankabfragen sicher mit der Methode AddWithValue() angefreundet haben.
Man gibt nur noch den Namen des Sql-Parameters und den entsprechenden Wert an und das .Net Framework kümmert sich um den Rest.
using (var conn = new SqlConnection(@"ConnectionString zensiert"))
{
conn.Open();
string sql = "Select LastName FROM TestTable WHERE LastName = @l";
var cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddWithValue("@l", "Harglgargl");
//selbes Ergebnis
//cmd.Parameters.Add("@l", "Meier");
object res = cmd.ExecuteScalar();
}
Ich würde erwarten, dass der SQL-Server schlau genug wäre und den Parameter korrekt auflöst.
Leider gibt es hier ein kleines Problem.
Führt man das Codefragment mit den Werten “Huber”, “Schmidt”, und “Harglgargl” aus würde man erwarten,
dass der SQL-Server einen bereits vorhandenen Ausführungsplan benutzt bzw. einen Plan für diese Abfrage erstellt und dann wiederverwendet.
Das Resultat sieht leider etwas anders aus:
Für jede Varchar-Länge wird ein eigener Ausführungsplan angelegt.
Die Auswirkungen werden bei einem genaueren Blick auf die Speicherausnutzung des SQL-Servers deutlich.
Mein Dev-Server sagt dazu auf jeden Fall Folgendes:
Cached: verwendeter Speicher um Seiten zu cachen
Stolen: Speicher der “gestohlen” wird um Ausführungspläne zu cachen
Das Verhältnis wird in den meisten Szenarien vernachlässigbar sein. Ich kann mir allerdings einige Umgebungen vorstellen in denen das Ganze zum Problem werden könnte.
Wie dem auch sei. Je mehr Speicher zur Verfügung steht um Seiten zu cachen umso besser
Die Lösung des Ganzen ist aktuell leider etwas umständlich. Man kann das Ganze umgehen indem man den Datentyp der entsprechenden Datenbankspalte angibt.
Leider ist das Ganze extrem lästig da es aktuell keine brauchbare Überladung gibt (Man kann sich natürlich eine schnitzen)…
using (var conn = new SqlConnection(@"ConnectionString zensiert"))
{
conn.Open();
string sql = "Select LastName FROM TestTable WHERE LastName = @l";
var cmd = new SqlCommand(sql, conn);
SqlParameter p = new SqlParameter("@l", System.Data.SqlDbType.VarChar, 1000);
p.Value = "Huber";
cmd.Parameters.Add(p);
object res = cmd.ExecuteScalar();
}
Wie ermittelt man die Torschützenkönige der Bundesliga aus einer Liste aller Torschützen der jeweiligen Saison ?
Das Ganze wäre prinzipiell mit Hilfe einiger Subqueries machbar.
Optimaler läßt sich das Ganze mit Hilfe der Funktion Rank() lösen die ab SQL-Server 2005 zur Verfügung steht.
SELECT Spieler, Verein, Tore, Saison, RANK() OVER (PARTITION BY Saison ORDER BY Tore DESC) AS Platz FROM #ErzielteTreffer
SELECT Spieler,Verein,Tore,Saison FROM ( SELECT Spieler, Verein, Tore, Saison, RANK() OVER (PARTITION BY Saison ORDER BY Tore DESC) AS Platz FROM #ErzielteTreffer ) AS Rangfolge WHERE Platz = 1
Excel 97 – 2003
SELECT
[ID], -- Excel Spalte 1
[Text] -- Excel Spalte 2
FROM
OPENDATASOURCE('Microsoft.Jet.OLEDB.4.0',
'Data Source=C:\test.xls;Extended Properties=Excel 8.0')
...[Tabelle1$] -- Tabellenblatt
ORDER BY
[ID] DESC
Excel 2007:
Um die Funktionalität auch bei .xslx-Dateien nutzen zu können, muß folgende Komponente auf dem System installiert sein:
2007 Office System Driver: Data Connectivity Components
SELECT * FROM OPENDATASOURCE( 'Microsoft.ACE.OLEDB.12.0', 'Data Source=C:\test.xlsx;Extended Properties=Excel 12.0') ...[Tabelle1$]
Leider funktioniert das Ganze aktuell nur auf 32-Bit Systemen, da die entsprechenden Provider auf 64-Bit Systemen derzeit nicht zur Verfügung gestellt werden.
SELECT * FROM OPENROWSET
('MSDASQL', 'DRIVER={SQL Server};SERVER=zensiert;UID=zensiert;PWD=zensiert,
Testdatenbank.Schema.TestTabelle)
WHERE ...
Um dieses Feature nutzen zu können muss folgendes Setting aktiviert sein
EXEC sp_configure 'Ad Hoc Distributed Queries', '1' RECONFIGURE
http://technet.microsoft.com/de-de/library/ms187569.aspx