当前位置: 首页 > 知识库问答 >
问题:

第二个查询不运行

越正阳
2023-03-14

在插入新记录之前,我正在验证记录的存在性。但是,代码不会跳入insert块。在Reader.Close之后跳转到finally block

我怀疑我一定是做错了什么,因为没有例外,而且每次RecordsInfacted=-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();
}

共有2个答案

商昂然
2023-03-14

如果您查看RecordsImpect的文档,就可以清楚地看到为什么您会得到-1:

更改、插入或删除的行数;如果没有行受影响或语句失败,则为0;和-1表示SELECT语句。

可以使用HasRows属性:

using(SqlDataReader reader = command.ExecuteReader())
{
    if (reader.HasRows)
    {
        // insert
    }
}
仉联
2023-03-14

Reader.RecordsImpect不可靠,最终不是为了这个目的;如果你想测试是否存在,那么...“对代码更改最少”的方法是增加计数器来计算行数:

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

或者更懒惰:

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

但是:那是不必要的嘈杂;您可以从...中选择count(1),但即使这样也是一个额外的往返行程。一个不错的想法可能是单个SQL操作(在同一批处理中执行存在和插入):

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

但即使这仍然是一个竞争条件,除非您有合适的事务隔离。

 类似资料:
  • 问题内容: 是否可以像这样有两个mysqli查询? 基本上,我想更新数据库中的两个表。有一个更好的方法吗? 问题答案: 可以使用mysqli_multi_query()。 例: 关键是如果要在单个调用中执行多个查询,则 必须 使用。出于安全原因,将不执行多个查询以防止SQL注入。 还请记住的行为。它返回如果查询没有结果集(这查询不),所以你还必须检查地看到,它返回一个空字符串意味着成功。

  • 假设我有一条这样的路线 我想在第二个查询中使用一些数据,这些数据将由第一个查询返回。但是现在我不能这样做,因为根据我的理解(如果我错了,请纠正我),这两个查询都是promise的,并且是异步工作的,所以它不会等待第一个查询的完成来执行第二个查询。 我将如何重写这一点,使第一个查询的执行总是在执行第二个查询之前首先完成?

  • 我从我的SQL工具(即Squirrel SQL、Oracle SQL Developer)与端口10000的HiveServer2(运行在远程服务器上)建立了一个JDBC连接。 我能够成功地运行一些查询。然后在1-2分钟内执行其他操作(不在SQL工具中),然后返回SQL工具并尝试运行查询,但我得到以下错误: 如果我现在断开连接并在我的SQL工具中重新连接,我可以再次运行查询。但是有人知道我应该更改

  • 我有两个查询写在同一时间这样: 在执行第二个查询之前,是否可以使用SQL指令或在代码中获取ID? 谢谢:)

  • 问题内容: 我试图加快PHP脚本的速度,目前正在Mysql域中推送一些PHP逻辑。如果第一个Select不返回行或计数为零,是否可以进行其他选择查询? 请记住,第一个查询需要首先运行,并且 仅 当第一个查询返回空集 时才 应激活第二个查询。 对于上面的2个查询,我有这段代码,但似乎每个查询运行两次(一次计数,一次返回)。有一个更好的方法吗? 问题答案: 一种选择是使用有: SQL小提琴演示 这将从

  • 我正在尝试加速一个PHP脚本,目前我正在推动一些PHP逻辑在Mysql领域的东西。如果第一个select没有返回行或计数为零,是否有方法进行不同的select查询? 请记住,需要首先运行第一个查询,只有在第一个查询返回一个空集时才应激活第二个查询。 对于上面的2个查询,我有这段代码,但它似乎要运行每个查询两次(一次用于计数,一次用于返回)。有没有更好的办法做到这一点?