C# - SELECT查询受影响的行数始终为-1

时间:2012-04-07 08:36:33

标签: c# sql-server

我有这个代码,它总是返回-1。我有三个表(图片更具暗示性): enter image description here

我想查看该行是否已经在ReservationDetails表中,如果它不是要插入它。

try
        {
            SqlConnection conn = new SqlConnection... 
            SqlCommand slct = new SqlCommand("SELECT * FROM ReservationDetails WHERE rID=@rID AND RNumber=@RNumber", 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

5 个答案:

答案 0 :(得分:7)

你应该

1)将您的TSQL更改为

 SELECT COUNT(*) FROM ReservationDetails WHERE ...

(更好的是,使用IF EXISTS ...)

2)并使用ExecuteScalar()

noRows = (int) slct.ExecuteScalar();

另外:你需要使用一个事务(或其他一些原子技术),否则有人可能会在你测试和插入它之间插入一行......

所有这一切,最好创建一个存储过程,给出您的参数,原子测试并插入表中,如果成功则返回1,如果行已存在则返回0

答案 1 :(得分:7)

您是否阅读了SqlCommand.ExecuteNonQuery的文档?

  

对于UPDATE,INSERT和DELETE语句,返回值是受命令影响的行数。当插入或更新的表上存在触发器时,返回值包括插入或更新操作影响的行数以及受触发器或触发器影响的行数。 对于所有其他类型的语句,返回值为-1。如果发生回滚,则返回值也为-1。

您的查询是SELECT。

答案 2 :(得分:2)

最好在单个查询中执行此操作,这样您就不需要两次请求服务器。

创建一个这样的过程并从代码中调用它。

IF EXISTS (SELECT 1 from ReservationDetails WHERE rID=@rID AND RNumber=@RNumber)
BEGIN
 insert into ReservationDetails values(@rID,@RNumber)
END

答案 3 :(得分:2)

根据微软:

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.

您可能需要的是,而不是ExecuteNonQuery是ExecuteScalar并将COUNT放在您的选择查询中。

SqlCommand slct = new SqlCommand("SELECT COUNT(*) FROM ReservationDetails WHERE   rID=@rID AND RNumber=@RNumber", conn);

另外,尝试在C#中使用using语句,这样即使事情失败,也不必担心手动关闭连接。

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

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

答案 4 :(得分:1)

@nickNatra

什么时候使用

  

选择命令

它将返回你的价值观。

可以使用哪个
  

DataSet或SqlDataReader

但是

  

command.ExecuteNonQuery()

仅在您使用

时使用
  

插入,更新,删除行在您的表格中生效的位置

是的,如果您确实想知道查询中有多少记录。 你可以执行

  

a)修改您的查询“从表中选择计数(*)

你只能得到一个值,即。行数。

  

b)使用此查询执行命令。 ExecuteScalar()仅返回第一行和第一列,即行数

因此,满足您的要求。

干杯!!