2015-12-15 5 views
7

Ich habe zwei SQL-Anweisungen in meinem C# -Code, um einige Werte abzurufen. Ich weiß, dass sie für SQL-Injection offen sind, da ich keine Parameter verwende, aber ich bin mir nicht sicher, ob ich sie richtig implementiere.Korrekte Sicherung der SQL-Anweisung mit Parametern

(Anmerkung: Jede von diesen sind in Schleifen, die durch die Zeilen einer Datentabelle sind Looping) Erstes Beispiel:

string sql2 = "select max(day) as day from users u join days d on d.User_ID = u.id where u.ActiveUser = 1 and u.id = " + Users["ID"].ToString(); 
command.CommandText = sql2;    
string dt = command.ExecuteScalar().ToString(); 

In der obigen Erklärung ist es ein Datumzeit abgerufen und auf String dt zuordnet. Alles mit ID oder ID ist ein Bigint.

string sql = "SELECT MAX(Day) FROM Days WHERE Project_ID IN (SELECT ID FROM Projects WHERE Parent_ID = -1 AND ID = " + row["ID"] + ") HAVING MAX(Day) < DATEADD(dd, -730, getdate())"; 
command.CommandText = sql;         
object val = command.ExecuteScalar(); 

Die obige Anweisung ist die gleiche wie die erste Anweisung, da sie einen Datetime-Wert abruft. Alles mit ID oder ID ist ein Bigint.

Hier ist, was ich für die erste kam, vermisse ich etwas oder etwas falsch machen?

string sql2 = "select max(day) as day from users u join days d on d.User_ID = u.id where u.ActiveUser = 1 and u.id = @userID"; 
using (conn) 
{ 
    using (SqlCommand cmd = new SqlCommand(sql2, conn)) 
    { 
      command.Parameters.AddWithValue("@userID", drUsers["ID"]); 
      conn.Open(); 
      dt = (DateTime)command.ExecuteScalar(); 
    } 
} 

Anmerkung: Ich stellte eine Frage der vergangenen Woche auf Datetime-Konvertierungen und es gab ein Problem, das nicht gelöst werden könnte, so könnte ich muss nur einen String-Version des Datetime verwenden, der zurückgegeben wird. Wird sich das auf irgendetwas auswirken?

+1

Wenn die Parameter in der Abfrage ist? – JNF

+0

Sorry, bearbeitet meinen Beitrag. – pfinferno

+1

Sieht OK aus. [Related] (http://stackoverflow.com/questions/265192/get-the-generated-sql-statement-from-a-sqlcommand-object) (siehe alle Antworten) [Siehe diese Erklärung] (http: // www.csharp-station.com/Tutorial/AdoDotNet/Lesson06) – JNF

Antwort

3

Es wäre wie:

string sql2 = @"select max(day) as day from users u 
join days d on d.User_ID = u.id 
where u.ActiveUser = 1 and u.id = @id"; 

string sql = @"SELECT MAX(Day) FROM Days 
WHERE Project_ID IN 
(SELECT ID FROM Projects WHERE Parent_ID = -1 AND ID = @id) 
HAVING MAX(Day) < DATEADD(dd, -730, getdate())"; 

DateTime dt; 
using (conn) 
{ 
    using (SqlCommand cmd = new SqlCommand(sql2, conn)) 
    { 
    cmd.Parameters.AddWithValue("@id", (Int64)Users["ID"]); 
    conn.Open(); 
    dt = (DateTime)cmd.ExecuteScalar(); 
    } 
} 

using (conn) 
{ 
    using (SqlCommand cmd = new SqlCommand(sql, conn)) 
    { 
    cmd.Parameters.AddWithValue("@id", (Int64)row["ID"]); 
    conn.Open(); 
    dt = (DateTime)cmd.ExecuteScalar(); 
    } 
} 

aus Performance-Gründen jedoch würde ich dies einmal pro Zeile in der Datentabelle nicht. Sie können einfach alle maximalen (Tag) Werte nach ID gruppiert nach Client-Seite bekommen. ie:

EDIT: Ich sah Ihre Bearbeitung später, und die zusätzliche Frage über Datetime. Konvertieren Sie einen Datetime-Wert nicht in eine Zeichenfolge. Hier beginnen die Fehler. Wenn Sie "HABEN", dann verwenden Sie nur das kanonische ODBC-Format, das nicht von den SQL Server-Einstellungen betroffen ist - yyyyMMdd. Andere Arten von datetime strings funktionieren nur zufällig, wenn sie es jemals tun.

+0

Nur tun es pro Reihe, weil ein Bündel anderer sql Sachen (vom vorherigen Kodierer) dort ist. Wenn ich es auf Ihre Art und Weise machen würde, würde ich einfach eine Liste von DateTimes machen und sie gleich w/e zurückgeben und sie dann durchlaufen? – pfinferno

+0

Sie würden einen einzelnen SQL-Aufruf ausführen und eine Liste mit der ID Max (Tag) zurückgeben. Dann könnten Sie sagen, konvertieren Sie es zu einem Dictionary mit einfachen Linq und verwenden Sie in Ihrer Schleife, anstatt mehrere SQLs in der Schleife. In Kommentaren weiß ich nicht, wie man Code formatiert (wenn ich kann), also poste ich ein Codebeispiel als neue Antwort. –

+0

Alles klar, danke. Ich weiß, dass es nicht gut ist, datetime in eine Zeichenkette zu konvertieren, aber etwas Seltsames passierte, als ich versuchte, das Datum zu formatieren. Ich habe hier in den letzten zwei Wochen zwei Fragen gestellt, und alles, was funktionieren sollte, tut es nicht. – pfinferno

0
string sql = @"select u.Id, max(day) as day 
    from users u 
    join days d on d.User_ID = u.id 
    where u.ActiveUser = 1 
    group by u.id"; 

DataTable tbl = new DataTable(); 
using (conn) 
{ 
    using (SqlCommand cmd = new SqlCommand(sql, conn)) 
    { 
    conn.Open(); 
    tbl.Load(cmd.ExecuteReader()); 
    conn.Close(); 
    } 
} 

var dates = tbl.AsEnumerable() 
       .ToDictionary(t => t.Field<Int64>("ID"), 
          t => t.Field<DateTime?>("Day")); 

in der Schleife Dann könnte man das sagen tun:

var myId = 4; 
var myDate = dates[myId]; 
Verwandte Themen