2012-04-07 18 views
2

ich diesen Code haben, und es gibt immer -1.I haben drei Tabellen (ein Bild ist mehr suggestive): enter image description hereC# - SELECT-Abfrage Anzahl der betroffenen Zeilen ist immer -1

Ich möchte sehen, ob die Zeile befindet sich bereits in der Tabelle ReservationDetails und wenn sie nicht eingefügt werden soll.

try 
     { 
      SqlConnection conn = new SqlConnection... 
      SqlCommand slct = new SqlCommand("SELECT * FROM ReservationDetails WHERE [email protected] AND [email protected]", conn); 
      slct.Parameters.AddWithValue("@rID", (int)comboBox1.SelectedValue); 
      slct.Parameters.AddWithValue("@RNumber", dataGridView1.SelectedRows[0].Cells[0].Value); 

      int noRows;//counts if we already have the entry in the table 
      conn.Open(); 
      noRows = slct.ExecuteNonQuery(); 
      conn.Close(); 
      MessageBox.Show("The result of select="+noRows); 

      if (noRows ==0) //we can insert the new row 
+4

Warum verwenden Sie 'ExecuteNonQuery' für eine' SELECT' Anweisung? –

+0

was soll ich dann benutzen? P.S. es ist kein großes Projekt, also wird niemand etwas einfügen :) – NiCU

Antwort

7

sollten Sie

1) Ändern Sie Ihre TSQL zu

SELECT COUNT(*) FROM ReservationDetails WHERE ... 

(noch besser, verwenden IF EXISTS ...)

2) und verwenden ExecuteScalar():

noRows = (int) slct.ExecuteScalar(); 

Außerdem: Sie müssen eine Transaktion (oder eine andere atomare Technik) verwenden, sonst könnte jemand eine Zeile dazwischen einfügen und versuchen, es einzufügen ...

All das gesagt, es wäre besser um eine gespeicherte Prozedur zu erstellen, die Ihre Parameter angibt, atomar testet und in die Tabelle einfügt, wobei 1 zurückgegeben wird, falls erfolgreich, oder 0, wenn die Zeile bereits existiert.

7

Haben Sie die Dokumentation von SqlCommand.ExecuteNonQuery gelesen?

Bei UPDATE-, INSERT- und DELETE-Anweisungen ist der Rückgabewert die Anzahl der vom Befehl betroffenen Zeilen. Wenn ein Trigger für eine Tabelle vorhanden ist, die eingefügt oder aktualisiert wird, enthält der Rückgabewert die Anzahl der Zeilen, die von der Einfüge- oder Aktualisierungsoperation betroffen sind, sowie die Anzahl der Zeilen, auf die sich der Trigger oder die Trigger auswirken. Für alle anderen Arten von Anweisungen ist der Rückgabewert -1. Wenn ein Rollback auftritt, ist der Rückgabewert ebenfalls -1.

Und Ihre Abfrage ist SELECT.

+0

ok, aber der kurze Bericht der Methode sagt "gibt die Anzahl der betroffenen Zeilen zurück" Ich dachte, es ist etwas rong in der Auswahl – NiCU

+2

@nickNatra: Wie viele Zeilen würden Sie erwarten zu sein * von einer Anfrage betroffen? Eine Abfrage wirkt sich nicht auf irgendetwas aus - sie fragt nur ab. –

+0

@ Jon Skeet: Wenn ich eine SELECT in der SQL Server-Verwaltung mache, heißt es "# row (s) betroffenen". – Carol

2

Es ist besser, es in einer einzigen Abfrage zu tun, so dass Sie den Server nicht zweimal anfordern müssen.

Erstellen Sie eine Prozedur wie diese und rufen Sie sie aus dem Code.

IF EXISTS (SELECT 1 from ReservationDetails WHERE [email protected] AND [email protected]) 
BEGIN 
insert into ReservationDetails values(@rID,@RNumber) 
END 
2

Per Microsoft:

You can use the ExecuteNonQuery to perform catalog operations (for example, querying the structure of a database or creating database objects such as tables), or to change the data in a database without using a DataSet by executing UPDATE, INSERT, or DELETE statements.

Was können Sie benötigen, statt ExecuteNonQuery ExecuteScalar ist und die COUNT in Ihre Auswahlabfrage setzen.

heißt

SqlCommand slct = new SqlCommand("SELECT COUNT(*) FROM ReservationDetails WHERE [email protected] AND [email protected]", conn); 

Versuchen Sie auch, den Einsatz der using-Anweisung in C# zu machen, so dass Sie die Verbindung kümmern müssen nicht manuell zu schließen, auch wenn die Dinge scheitern.

, d.h.

using (SqlConnection conn = new SqlConnection(connString)) 
{ 
    SqlCommand cmd = new SqlCommand(sql, conn); 
    try 
    { 
     conn.Open(); 
     newProdID = (Int32)cmd.ExecuteScalar(); 
    } 
    catch (Exception ex) 
    { 
     //Do stuff 
    } 
} 

siehe: http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executescalar.aspx

1

@nickNatra

Wann immer Sie

Select Befehl

Es wird Sie Werte zurückgeben. Die entweder durch

DataSet oder SqlDataReader

Aber

command.ExecuteNonQuery()

wird nur verwendet, wenn Sie

verwenden

Einfügen, Aktualisieren, Löschen, wo die Zeilen in der Tabelle bewirkt werden immer

Ja, wenn Sie, wie viel Datensätze es in Ihrer Abfrage sind Sie wissen wollen. Sie können ausführen

a) Ändern Sie bitte Ihre Abfrage "select count (*) aus Tabelle"

, wo man nur einen Wert, dh bekommen. Anzahl der Reihen.

b) Mit dieser Abfrage Befehl ausführen. ExecuteScalar(), die zurückkehren wird nur erste Reihe und erste Spalte, die das Row Count

Daher dies Ihre Anforderung der befriedigen.

Prost !!

Verwandte Themen