2017-10-18 23 views
1

Ich verwende OLEDB-Verbindung, um Daten aus Excel-Dateien zu lesen. Beim Verwenden des IN-Operators in der Select-Abfrage treten Probleme auf. Unten ist meine Frage,IN Operator in OLEDB

string EmployeeIds = "'1231','1232','1233'"; 
SELECT [Employee Number],[Employee Name],[First In Time],[Last Out Time],[Total Work Hours] 
FROM [Sheet0$A2:J] 
WHERE [Employee Number] IN (?); 

comm.Parameters.AddWithValue("?",EmployeeIds); 

ich leer Ergebnisse bin immer, aber wenn ich nur Einzelwert geben dann ich immer Ergebnis bin. Bitte helfen Sie.

Antwort

3
where someval in ('123,456,789') 

ist sehr unterschiedlich zu:

where someval in (123,456,789) 

Die zweite Zeile someval gegen 3 numerische Werte Tests; die erste Zeile testet someval gegen einen einzelnen Zeichenfolge Wert, die Zahlen und Kommas enthält (aber diese Zahlen und Kommas sind irrelevant).

Sie können nicht tun, was Sie wollen, ohne (einer):

  • die SQL dynamisch schreiben einen Parameter pro Wert aufweisen, dh in (?,?,?,?)
  • die Nutzung einiger Funktion des Back-End die Spaltung zu tun - zum Beispiel STRING_SPLIT in neueren Versionen von SQL Server (dies wird sehr Backend-spezifisch sein); Ich weiß nicht genug über Excel, um darüber zu beraten, ob ein solches Feature existiert.
3

Dies ist ein sehr häufiger Fehler.
Der Operator IN erwartet eine Liste der Werte, aber Sie liefern einen einzigen Wert, der zufällig eine Liste enthält. Sie sollten für jeden Wert in der EmployeeIds-Liste einen anderen Parameter erstellen. Hier

ist eine Möglichkeit, es zu tun:

string EmployeeIds = "'1231','1232','1233'"; 
var values = EmployeeIds.Split(','); 

using(var command = new OleDbCommand()) 
{ 
    var sql = "SELECT [Employee Number], [Employee Name], [First In Time], [Last Out Time], [Total Work Hours] "+ 
       "FROM [Sheet0$A2:J] "+ 
       "WHERE [Employee Number] IN ("; 

    for(int i=0; i < values.Length; i++) 
    { 
     // Please note that string interpolation will work only with c# 6 or later. 
     // If you are working with vs 2013 or earlier, use string.Format instead. 
     sql = $"{sql} @{i},"; 
     command.Parameters.Add($"@{i}", OleDbType.Int).Value = values[i].Trim(new char[] {'}); // You don't need the ' anymore since you are working with parameters now... 
    } 

    command.CommandText = sql.TrimEnd(',') +");"; 
    command.Connection = con; 
    using(var reader = Command.ExecuteReader()) 
    { 
     while(reader.Read()) 
     { 
      // do your stuff with the data 
     } 

    } 
} 
+0

Etwas, es besser zu machen: eine Liste Verwenden Sie die Parameter Platzhalter zu speichern (und sie sollten sein, weil wir nicht wissen, die zugrunde liegenden db „?“) und erstellen Sie die letzte Abfrage nur mit string.Join anstelle von vielen String-Operationen (mit einer Menge von Parametern könnte es ein Leistungsproblem sein), auch Parameter sind vom Typ OleDb.Int32, aber das op verwendet Strings. Dies könnte je nach Motor funktionieren oder nicht. Besser das Richtige tun und sie konvertieren – Steve

+0

@Steve du meinst wie [deine Antwort hier] (https://Stackoverflow.com/a/46471904/3094533)? Ich dachte tatsächlich darüber nach, entschied aber, dass es eine Art Plagiat sein würde, und obwohl es die aufrichtigste Form der Schmeichelei ist, denke ich, dass ich besser Kredit belasse, wo der Kredit fällig ist :-) –

+0

Ah Das war, wo es war. Vielleicht sollten wir das als Duplikat dann schließen, aber es ist nicht möglich. Ziemlich sicher gibt es andere Duplikate um – Steve