2017-06-27 4 views
0

Ich habe eine SQL-Anweisung, die 161 Zeilen zurückgegeben wurde. Wenn ich eine zusätzliche Spalte hinzufügte, die NICHT ein Schlüssel ist, erhöht sich die Anzahl der Zeilen, die ich zurückerhalte, auf über 5000, von denen die allermeisten völlig leer sind.Hinzufügen einer Spalte fügt Tausende von leeren Zeilen hinzu

Die sql-Anweisung soll eine Liste von Konfigurationen für einen Kunden aufnehmen und alle übereinstimmenden Konfigurationen von einem anderen Kunden anzeigen ("übereinstimmend" bedeutet, dass er denselben Konfigurationsnamen hat). Ich muss sehen, ob es eine Übereinstimmung hat oder nicht, und auch die Konfigurationsdaten für diejenigen ohne eine Übereinstimmung haben.

Mein Code:

... 

    var myTable = new DataTable(); 
    try 
    { 
     string sql = "SELECT SourceConfig.ConfigurationId AS 'SourceID', " + 
          "SourceConfig.Name, " + 
    /* Added this line */ "SourceConfig.ConfigurationData AS 'SourceData', " + 
          "TargetConfig.ConfigurationId AS 'TargetID' " + 
        "FROM ConfigurationTable SourceConfig " + 
        "LEFT JOIN ConfigurationTable TargetConfig ON " + 
         "(TargetConfig.CustomerID = " + getTargetID() + " AND " + 
         "SourceConfig.Name = TargetConfig.Name)" + 
        "WHERE SourceConfig.CustomerId = " + getSourceID(); 
     myTable = this.accessService.FetchDataFromCustomerDatabase(sql); 
     myTable.PrimaryKey = new DataColumn[1] { myTable.Columns[0] }; // Error here 
    } 
    catch (Exception e) 
    { 
     // Record error message 
     return; 
    } 

    // Do stuff with 'myTable' 
... 

Mein vorherigen Code nicht haben, dass der 3. Zeile der SQL-Anweisung in der ‚Configuration‘ zu bringen, aber warum sollte das Hinzufügen dieser Zeile Ursache dieser Fehler? Die Spalte 'ConfigurationData' ist kein Schlüssel, primär oder nicht. Ich habe versucht, eine weitere WHERE-Bedingung hinzuzufügen, um Nullwerte auszuschließen, aber ich bekomme immer noch Tausende von Zeilen.

Der eigentliche Kicker ist, dass dieser Fehler nicht auftritt, wenn ich die gleiche SQL-Anweisung in "Microsoft SQL Management Studio" ausführen. Dort drüben bekomme ich noch 161 Zeilen zurück; Nur wenn ich meinen C# -Code in Visual Studio starte, werde ich mit diesen leeren Zeilen bombardiert.

Ich denke, das Problem hängt mit dem Datentyp der neuen Spalte zusammen, die von SQL Management Studio als "(XML (.), Not null)" bezeichnet wird. Ich habe versucht, andere Spalten anstelle von 'ConfigurationData' hinzuzufügen, und es ist nur derjenige, der so explodiert.

+6

Ihr Code ist anfällig für SQL-Injektion. Sie sollten Parameter verwenden. – Cameron

+1

Wenn Sie vermuten, dass Ihre Datenschicht das Problem ist, untersuchen Sie Ihre Datenschicht. Öffnen Sie die schwarze Box, die 'FetchDataFromCustomerDatabase()' ist. –

+0

Ich bin entsetzt über die Idee, diese Box zu öffnen, aber wenn es der einzige Weg ist ... auch, guter Punkt auf der SQL-Injektion, sollte ich das vielleicht für später nicht verlassen. –

Antwort

0

Also, während ich versuchte, mich gegen SQL-Injektion zu schützen, endete ich mein ursprüngliches Problem zu beheben. Stelle dir das vor. Ich fand die Lösung von hier: Read SQL Table into C# DataTable

Im Wesentlichen war das Problem mit "FetchDataFromCustomerDatabase()", und ich verwende diese Methode nicht, wenn ich Dinge auf die sichere Weise mache. Der neue Code:

... 

    var myTable = new DataTable(); 
    try 
    { 
     using (SqlConnection connection = new SqlConnection(ConnectionString)) 
     { 
      string sql = "SELECT SourceConfig.ConfigurationId AS 'SourceID', " + 
           "SourceConfig.Name, " + 
           "SourceConfig.ConfigurationData AS 'SourceData', " + 
           "TargetConfig.ConfigurationId AS 'TargetID' " + 
         "FROM ConfigurationTable SourceConfig " + 
         "LEFT JOIN ConfigurationTable TargetConfig ON " + 
          "(TargetConfig.CustomerID = @targetCustID AND " + 
          "SourceConfig.Name = TargetConfig.Name)" + 
         "WHERE SourceConfig.CustomerId = @sourceCustID"; 

      var command = new SqlCommand(sql, connection); 
      command.Parameters.Add("@sourceCustID", SqlDbType.Int); 
      command.Parameters.Add("@targetCustID", SqlDbType.Int); 
      command.Parameters["@sourceCustID"].Value = sourceCustID; 
      command.Parameters["@targetCustID"].Value = targetCustID; 

      var da = new SqlDataAdapter(command); 
      da.Fill(myTable); 
      da.Dispose(); 

      myTable.PrimaryKey = new DataColumn[1] { myTable.Columns[0] }; 
     } 
    } 
    catch (Exception e) 
    { 
     // Record error message 
     return; 
    } 

    // Do stuff with 'myTable' 
... 
Verwandte Themen