检查数据表是否为空。

12

以下是我一直在使用的代码,用于从SQL数据库中检索用户信息。

            string userName = LoginUser.UserName;
            string password = LoginUser.Password;
            string comm = "SELECT Username,Password,Clientname,Role FROM Users WHERE Username = '" + userName + "';";
            bool rememberUserName = LoginUser.RememberMeSet;

            SqlConnection conn = new SqlConnection(connstring);
            conn.Open();

            SqlCommand command = new SqlCommand(comm, conn);
            SqlDataAdapter da = new SqlDataAdapter(command);
            DataTable dt = new DataTable();
            da.Fill(dt);
            DataRow dr = dt.NewRow();
            if (dt != null)
            {
                //logic
            }

然而,当数据库中没有与LoginUser.Username相等的用户名时,(dt != null)并不返回false。是否有不同的方法来检查sqlcommand是否成功?


13
我的用户名可以是“foo 'drop table Users - mwahahah”吗? - Marc Gravell
赞同@MarcGravell - 了解SQL注入的相关知识,此外,接受一些答案。 - infojolt
是的,这应该至少是一个参数化查询。 - KeithS
3
您或许希望采纳一些已经回答过的6个问题的答案;当人们给您好的回答并得到奖励时,这有助于网站更好地运作。 - tmesser
这只是一个样例数据库,我正在学习如何进行登录认证。安全性方面我会在以后处理。 - Tony
2
如果你正在学习登录认证,为什么不学习如何正确地进行认证呢? - infojolt
7个回答

37

如果没有记录匹配,您将获得一个空的DataTable,因此您可以检查返回的记录数量:

if (dt.Rows.Count > 0)

稍微离题一下,请阅读你的问题下面的评论,然后搜索SQL注入和参数化SQL语句这些术语。可以从这里开始。


当我正在输入时,我收到了通知,说你已经抢先完成了。 :) - Ari Roth
3
不要使用 rows.Count,因为它会查询有多少行存在。如果有很多行,计数会花费一些时间。您真正想知道的只是“是否至少有一行?”您不关心是否有10行、1000行还是10亿行。您只想知道是否至少有一行。如果我给你一个盒子,并问你里面是否有弹珠,你会把盒子倒在桌子上开始数吗?当然不会。请使用以下代码来检查 DataTable 是否为空:bool hasRows = dataTable1.Rows.Any() - ger

15

为什么不稍微修改一下语句来查看 DataTable 是否为 null 或没有行:

if(dt != null && dt.Rows.Count > 0)

另外,顺便提一下,你还应该研究参数化查询,而不是动态构建SQL。这将减少攻击者试图危及您的应用程序时的攻击点。


2
dt 被明确设置为 new DataTable();它会 永远 是 null 吗? - KeithS
@KeithS - 不是。但我也不确定上面的代码是示例还是完整的代码。无论哪种情况,它都没有造成任何损害。 - Justin Niessner

2
截至C# 6.0,你可以使用空值条件运算符?.(或数组的?[])。 空值条件运算符简化了语句:
if (dt?.Rows?.Count > 0)

当以下情况发生时,该函数返回false:

  1. 数据表dt为空
  2. 数据表行dt.Rows为空
  3. 行数dt.Rows.Count为0

使用空值条件运算符,您可以避免手动检查数据表和计数属性,例如 if (dt != null && dt.Rows.Count > 0)

"Original Answer"翻译成"最初的回答"

1

对于这个任务来说,使用 DataTable 和 SqlDataAdapter 似乎有点过重。

你可以在这里只使用 DataReader:

        SqlCommand command = new SqlCommand(comm, conn);
        using (var reader = command.ExecuteQuery()) 
        {
            if (reader.Read())
            {
                //logic
                var userName = reader.GetString(0);
                var password = reader.GetString(1);
                // etc
            }
        }

0

对于 DataSet,您可以这样检查:

if (ds.Tables[0].Rows.Count > 0)

0

我知道这个问题很老了,答案在它发布的时候有所帮助,但现在有一种简单的解决方法:

if ((dataTableName?.Rows?.Count ?? 0) > 0)

0

如果您使用try catch来检查表格是否为空,只需处理IndexOutOfRangeException异常,效果会更好。

请使用以下逻辑:

try
{
   //dataTable operations
}
catch(IndexOutOfRangeException)
{
}

对我来说它正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,