简体   繁体   English

第二个查询不运行

[英]The second query does not run

I am validating existance of a record before it inserts new record in. However the code does not jump into insert block.我在插入新记录之前验证记录的存在。但是代码不会跳转到插入块。 it jumps to finally block after reader.close它在 reader.close 之后跳转到 finally 块

i suspect i must be doing something wrong as there is no exceptions and the recordsaffected =-1 every time我怀疑我一定做错了什么,因为没有例外,并且每次都影响记录=-1

{
    // check if data exists before inserting
    command.Connection = connection;
    command.CommandType = CommandType.Text;
    command.CommandText = " SELECT id from  [dbo].[trade_events]  where  instrument =@instrument and datetime>@datetime and eventname=@eventname";
    command.Parameters.AddWithValue("@datetime", dt);
    command.Parameters.AddWithValue("@instrument", instrument);
    command.Parameters.AddWithValue("@eventname", eventname);
    connection.Open();
    SqlDataReader reader = command.ExecuteReader();
    while (reader.Read()) ;
    reader.Close();
    if (reader.RecordsAffected <= 0)
    {
        // <== insert data now

        command.CommandText = " INSERT INTO [dbo].[trade_events]  ([datetime] ,[instrument],[source],[eventname],[eventdetails],[state],[account],[connection]) " +
                              "values(@datetime, @instrument,@source, @eventname,@eventdetails,@state,@account,@connection)";

        //  command.CommandText = "UPDATE [dbo].[Alerts] SET [datetimealertrecieved] = @timerecieved where  instrument=@instrument and alertType =@alerttype and  datetimealertrecieved is null" ;

        command.Parameters.AddWithValue("@datetime", dt);
        command.Parameters.AddWithValue("@instrument", instrument);
        command.Parameters.AddWithValue("@source", source);
        command.Parameters.AddWithValue("@eventname", eventname);
        command.Parameters.AddWithValue("@eventdetails", eventdetails);
        command.Parameters.AddWithValue("@state", state);
        command.Parameters.AddWithValue("@account", account);
        command.Parameters.AddWithValue("@connection", dataconnection);

        connection.Open();
        int recordsAffected = command.ExecuteNonQuery();
    }

}
catch (SqlException ex)
{
    // error here
    var notice = airbrake.BuildNotice(ex);
    var response = airbrake.NotifyAsync(notice).Result;
    notice = airbrake.BuildNotice(command.CommandText);
    response = airbrake.NotifyAsync(notice).Result;
}
finally
{
    connection.Close();
}

If you look at the documentation of RecordsAffected it's clear why you get -1:如果您查看RecordsAffected的文档,就很清楚为什么会得到 -1:

The number of rows changed, inserted, or deleted;更改、插入或删除的行数; 0 if no rows were affected or the statement failed;如果没有行受到影响或语句失败,则为 0; and -1 for SELECT statements .和 -1 表示 SELECT 语句

You can use the HasRows property:您可以使用HasRows属性:

using(SqlDataReader reader = command.ExecuteReader())
{
    if (reader.HasRows)
    {
        // insert
    }
}

You have to clear previous parameters before adding the new ones:在添加新参数之前,您必须清除以前的参数:

var cont=false;
  while (reader.Read())

{
....your code
 cont=true ;
}
reader.Close();

if (cont)
{

command.Parameters.Clear();

 command.Parameters.AddWithValue("@datetime", dt);
        command.Parameters.AddWithValue("@instrument", instrument);
        command.Parameters.AddWithValue("@source", source);
        command.Parameters.AddWithValue("@eventname", eventname);
.....
}

reader.RecordsAffected isn't reliable, and isn't intended for this, ultimately; reader.RecordsAffected不可靠,最终也不打算用于此; if you're trying to test for existence, well... the "least changes to the code" way would be to increment a counter to count the rows :如果您正在尝试测试是否存在,那么......“对代码的最少更改”方式是增加一个计数器来计算行数

int records = 0;
while (reader.Read()) records++;
if (records == 0) {...}

or perhaps the more lazy:或者更懒惰:

bool any = reader.Read();
if (any) {...}

but: that's unnecessarily noisy;但是:那是不必要的嘈杂; you could select count(1) from... , but even that is an extra round trip.可以select count(1) from... ,但即使这样也是一个额外的往返。 An OK-ish idea might be the single SQL operation (that does the existence and insert in the same batch):一个好的想法可能是单个 SQL 操作(在同一批次中存在并插入):

if not exists (
    select id from  [dbo].[trade_events]
    where  instrument =@instrument and datetime>@datetime and eventname=@eventname
)
begin
    insert into ...
end

but even this is still a race condition, unless you have suitable transactional isolation.即使这仍然是一个竞争条件,除非你有合适的事务隔离。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么这个 LinqPad 程序在第二次运行时会产生不同的结果? - Why does this LinqPad program produce different results on the second run? 为什么此代码仅在第二次运行时才有效? - Why does this code only work the second time it is run? 为什么此函数第二轮运行速度快几个数量级? - Why does this function run orders of magnitude faster the second time round? Linq-to-SQL何时运行查询? - When does Linq-to-SQL run the query? 更新查询无法识别在其上运行的表的字段 - Update query does not recognize the fields of the table it is run on 如果不同的结果架构,Dapper第二次运行查询时会引发异常 - Dapper throws exception second time you run a query if different results schema 通过RSS进行的Facebook通知轮询第二次运行失败,有人知道为什么吗? - Facebook notification polling via RSS fails on second run, does anyone know why? 为什么为Task.Run()方法存在`CancelationToken`类型的第二个参数? - Why does exist a second parameter of `CancelationToken` type for Task.Run() method? 不执行第二个查询? - Not executing second query? 对我来说不错但无法运行的MS Access查询 - An MS Access query that looks good to me but does not run
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM