简体   繁体   English

如何在C#中将SELECT COUNT语句的结果作为字符串返回?

[英]How do I return the result of a SELECT COUNT statement as a string in C#?

I'm wondering how to return the result from a SELECT COUNT statement in C#. 我想知道如何从C#中的SELECT COUNT语句返回结果。

I have a sql statement that returns the count of 15. 我有一个sql语句,返回15的计数。

Currently, I'm returning the datareader. 目前,我正在返回datareader。 Can I somehow return the result of that as a string? 我能以某种方式将结果作为字符串返回吗?

    static public SqlDataReader FillDataReader(string sql, SqlParameter[] parms)
{
    SqlConnection conn = new SqlConnection(ConnectionString);
    SqlCommand cmd = new SqlCommand(sql, conn);
    SqlDataReader dr = null;
    conn.Open();
    cmd.CommandTimeout = 120; //120 seconds for the query to finish executing

    foreach (SqlParameter p in parms)
    {
        cmd.Parameters.Add(p);
    }
    try
    {
        dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
    }
    catch (SqlException ex)
    {
        if (dr != null)
        {
            dr.Close();
        }
        conn.Close();


        //DBUtilExceptionHandler(ex, sql);

        throw ex;


    }
    finally
    {
    }

    return dr; //This could be null...be sure to test for that when you use it

}

Or I could use a different method. 或者我可以使用不同的方法。 I just don't know what it should be. 我只是不知道应该是什么。

Any help is appreciated. 任何帮助表示赞赏。

This is my select statement: 这是我的选择声明:

        select count(LeadListID) from LeadLists WHERE SalesPersonID = 1
AND LeadListDateCreated BETWEEN '9/1/11' AND '10/1/11 23:59:59'

Sure - just use: 当然 - 只需使用:

int count = (int) query.ExecuteScalar();
// TODO: Decide the right culture to use etc
return count.ToString();

Notes: 笔记:

  • Use using statements instead of manual try/catch/finally blocks 使用using语句而不是手动try / catch / finally块
  • You should close the connection whether or not there was an error 无论是否有错误,都应关闭连接
  • Given that the natural result of the query is an integer, I would change it to return an int , not a string . 鉴于查询的自然结果是整数,我会将其更改为返回int ,而不是string Let the caller make that conversion if they want to 如果他们愿意,让调用者进行转换
  • If there's an error, you should almost certainly let the exception bubble up, rather than returning null 如果出现错误,您几乎肯定会让异常冒泡,而不是返回null

I would write the code as: 我会把代码编写为:

public static int ExecuteScalarInt32(string sql, SqlParameter[] parms)
{
    using (SqlConnection conn = new SqlConnection(ConnectionString))
    using (SqlCommand command = new SqlCommand(sql, conn) { Parameters = parms })
    {
        conn.Open();
        command.CommandTimeout = 120;
        return (int) command.ExecuteScalar();
    }
}

If you really needed a version to work on an arbitrary data reader, you could write it as: 如果您真的需要一个版本来处理任意数据读取器,您可以将其写为:

public static T ExecuteQuery<T>(string sql, SqlParameter[] parms,
                                Func<SqlDataReader, T> projection)
{
    using (SqlConnection conn = new SqlConnection(ConnectionString))
    using (SqlCommand command = new SqlCommand(sql, conn) { Parameters = parms })
    {
        conn.Open();
        command.CommandTimeout = 120;
        return projection(command.ExecuteReader());
    }
}

And then call it with: 然后调用它:

int count = ExecuteQuery<int>(sql, parms, reader => {
                                  if (!reader.MoveNext()) {
                                      throw new SomeGoodExceptionType("No data");
                                  }
                                  return reader.GetInt32(0);
                              });

Sure, you can always call the ToString() method in .NET on the single field when reading it: 当然,您可以在读取时在单个字段上调用.NET中的ToString()方法:

dr[0].ToString()

Are there many records that you want to concat as a string? 是否有许多记录要作为字符串连接? Then you loop through each row, grab the value as a string, and create a master string in a for loop fashion. 然后循环遍历每一行,将值作为字符串获取,并以for循环方式创建主字符串。

Since you're expecting only a single value, a better alternative to ExecuteReader is the ExecuteScalar method: 由于您只期望一个值,因此ExecuteReader一个更好的替代方法是ExecuteScalar方法:

try
{
    var count = cmd.ExecuteScalar().ToString();
}

Either cast it as a varchar in your sql: 在sql中将其转换为varchar:

select cast(count(LeadListID) as varchar(10))
from LeadLists 
WHERE SalesPersonID = 1
AND LeadListDateCreated BETWEEN '9/1/11' AND '10/1/11 23:59:59'

or just call .ToString() on the result, as shown in other answers. 或者只是在结果上调用.ToString(),如其他答案所示。

Additionally, I'm not a fan of relying on CommandBehavior.CloseConnection for DataReaders. 另外,我不依赖于CommandBehavior.CloseConnection I much prefer code like this: 我更喜欢这样的代码:

static public IEnumerable<IDataRecord> GetDataReader(string sql, SqlParameter[] parms)
{
    using (var conn = new SqlConnection(ConnectionString))
    using (var cmd = new SqlCommand(sql, conn))
    {
        cmd.CommandTimeout = 120; //120 seconds for the query to finish executing

        foreach (SqlParameter p in parms)
        {
            cmd.Parameters.Add(p);
        }

        conn.Open();
        using (var dr= cmd.ExecuteReader())
        {
            while (dr.Read())
            {
                yield return dr;
            }
        }
    }
}

Use ExecuteScalar instead, that will return the first field from the first record of the returned recordset, which is what you want. 改为使用ExecuteScalar,它将返回返回记录集的第一个记录中的第一个字段,这是您想要的。 That will return to you an object that is really an integer. 这将返回一个实际上是整数的对象。 Add a ToString to that and you should be good. 添加一个ToString,你应该是好的。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM