【问题标题】:Check if record in a table exist in a database through ExecuteNonQuery通过 ExecuteNonQuery 检查表中的记录是否存在于数据库中
【发布时间】:2013-07-28 00:09:37
【问题描述】:

在我的程序中,我需要使用if 语句检查表中是否已经存在数据库中的记录。 使用 c# 我试图通过 sql 连接来做到这一点。 因为我认为ExecuteNonQuery(); 命令返回一个整数值,如果我的假设是真的,我想知道什么值是真的,以知道表中是否存在某个记录。这是我的代码示例:

using (SqlConnection sqlConnection = dbUtil.GetSqlConnection(dbUtil.GetConnectionStringByName("NonConnectionString")))
{
    using (SqlCommand sqlCommand = new SqlCommand("SELECT * from users where user_name like 'Adam' AND password like '123456'", sqlConnection))
    {
        sqlresult = sqlCommand.ExecuteNonQuery();
    }
}

考虑到 sqlresult 之前已在 main 中初始化为 int sqlresult; 所以我想知道,这个用户“亚当”是否存在于数据库中。如果他存在,那么我想继续使用“if”语句,例如:

if(sqlresult == 0)
{
   MessageBox.Show("Adam exists!");
}

所以我只是不知道它应该返回的整数,而且我不确定这是不是这样做的正确方法。

谢谢。

【问题讨论】:

    标签: c# sqlcommand


    【解决方案1】:

    您应该使用ExecuteScalar 来检查记录是否存在。 ExecuteNonQuery 针对连接运行 transact-SQL 语句,并返回 UPDATE、INSERT 或 DELETE 影响的行数。它不适用于 SELECT 语句

    【讨论】:

      【解决方案2】:

      您应该在表格上执行count(1) 而不是select * 然后executescalar 以获得该整数值。

      使用您现有的代码,我会将其更改为:

      using (SqlConnection sqlConnection = dbUtil.GetSqlConnection(dbUtil.GetConnectionStringByName("NonConnectionString")))
              {
                  using (SqlCommand sqlCommand = new SqlCommand("SELECT count(1) from users where user_name = 'Adam' AND password = '123456'", sqlConnection))
                  {
                      sqlresult = sqlCommand.ExecuteNonQuery();
                  }
              }
      

      请注意,我使用了 equals 值而不是 like 值。

      另外,如果我这样做,我会更改您的内联 sql 以使用存储过程。

      【讨论】:

        【解决方案3】:

        如果要检查用户是否存在,则必须更改sql并使用COUNTEXISTS

        所以不是

        SELECT * from users where user_name like 'Adam' AND password like '123456'
        

        这个

        SELECT COUNT(*) from users where user_name like 'Adam' AND password like '123456'
        

        现在您可以使用ExecuteScalar 检索具有此用户名和密码的用户数:

        int userCount = (int) sqlCommand.ExecuteScalar();
        if(userCount > 0)
            // user exists ....
        

        注意你应该使用sql-parameters来防止sql-injection:

        using (SqlCommand sqlCommand = new SqlCommand("SELECT COUNT(*) from users where user_name like @username AND password like @password", sqlConnection))
        {
            sqlConnection.Open();
            sqlCommand.Parameters.AddWithValue("@username", userName);
            sqlCommand.Parameters.AddWithValue("@password", passWord);
            int userCount = (int) sqlCommand.ExecuteScalar();
            ...
        }
        

        【讨论】:

        • 值得注意的是 sqlCommand.ExecuteScalar() 返回的是 Object 而不是 int:msdn.microsoft.com/en-us/library/…
        • 感谢这个很好的例子,我有一个问题,从您的“使用”块代码中,userCount 变量中是否缺少转换为 int 的对象?还是不需要?
        • @WhySoSerious:感谢您的关注,我已经添加了它,因为它丢失了。正如@TonE 已经提到的那样,它是必需的,因为ExecuteScalar 返回object
        • 我想知道这会降低性能吗?即计数返回select * from ... 的查询结果还是只返回一个int?这意味着您必须检查 int 值,然后执行查询以返回该结果?
        • Count 只返回一个 int。但是,如果您想要最有效的版本,请使用 EXISTS 并返回一点。它会更有效率,因为它可以在找到第一个匹配记录后立即返回该位,而 COUNT 必须评估所有记录以确定计数。
        【解决方案4】:

        我会使用 Select Top 1 Id 而不是 count(*),因为它可以更快

        【讨论】:

        • 这是真的。前段时间,因为我改变了它,我获得了显着的性能提升。
        【解决方案5】:

        如果有一天你想使用 EF 就这样做:

        private MyDb db = new MyDb();
        
        public bool UserExists(string userName, string password){
        
           return db.Users.Any(x => x.user_name.Equals(userName, StringComparison.InvariantCultureIgnoreCase)
                                 && x.password.Equals(password, StringComparison.InvariantCultureIgnoreCase));
        }
        

        或者做一个泛型方法,这样你就可以处理多个实体:

        public bool EntityExists<T>(Expression<Func<T, bool>> predicate) where T : class, new()
        {
           return db.Set<T>().Any(predicate);
        }
        

        用法:

        EntityExists<Users>(x => x.user_name.Equals(userName, StringComparison.InvariantCultureIgnoreCase)
                              && x.password.Equals(password, StringComparison.InvariantCultureIgnoreCase));
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-08-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-07-28
          • 2019-01-25
          相关资源
          最近更新 更多