SQL/C# - 执行查询的最佳方法

17

我需要在C#类内执行一条SQL查询语句,我想到了两个选项:

  1. 启动sqlcmd进程。
  2. 使用SqlCommand对象。

我的问题是哪种方法更好?重要的是解决方案只能短时间保持与服务器的连接。

如果上述方法不好,我也可以接受其他建议。

谢谢您提前的帮助。


您是否期望返回一组记录集以供应用程序使用,还是仅尝试运行查询并继续进行? - TheDevOpsGuru
你是想特别避免连接池,还是只是想遵循最佳实践? - D'Arcy Rittich
抱歉表述不够清晰。查询是插入操作,结果并不需要。 - Ash Burlaczenko
回复较晚。sqlcmd.exe 比 SqlCommand 运行得快得多。sqlcmd.exe 有创建 csv 文件的选项。您可以使用 Process 类在 c# 中执行 sqlcmd.exe 。当进程完成后,您可以将 csv 文件读入 c#。 - jdweng
5个回答

31

使用SqlCommand。这段代码只会保持连接很短的时间(只要你的查询很高效):

DataTable results = new DataTable();

using(SqlConnection conn = new SqlConnection(connString))
    using(SqlCommand command = new SqlCommand(query, conn))
        using (SqlDataAdapter dataAdapter = new SqlDataAdapter(command))
           dataAdapter.Fill(results);

这取决于它是否会保持连接短暂的活动状态。如果您不小心,它可能会在整个应用程序的生命周期中保持连接甚至不止一个,而是多个。有关详细信息,请参阅我的答案。 - Darin Dimitrov
我该如何使用您的代码实现我想要做的事情:http://stackoverflow.com/questions/23617661/why-the-sql-command-is-not-executing - SearchForKnowledge

7
MSDN
以下示例创建了一个SqlConnection、一个SqlCommand和一个SqlDataReader。该示例通过数据,将其写入控制台。最后,该示例在退出Using代码块时关闭SqlDataReader然后关闭SqlConnection。
using System.Data.SqlClient

...

private static void ReadOrderData(string connectionString)
{
    string queryString = "SELECT OrderID, CustomerID FROM dbo.Orders;";

    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        SqlCommand command = new SqlCommand(queryString, connection);
        connection.Open();
        SqlDataReader reader = command.ExecuteReader();
        try
        {
            while (reader.Read())
            {
                Console.WriteLine(String.Format("{0}, {1}",
                    reader[0], reader[1]));
            }
        }
        catch (SqlException e)
        {
            Console.WriteLine(e.StackTrace);
            Console.WriteLine(e.Message);
        }
        finally
        {
            // Always call Close when done reading.
            reader.Close();
        }
    }
}

4

这要看情况。如果您不关心查询结果,那么使用sqlcmd可能是可以的。但是,如果您需要控制结果,最好使用ADO.NET。为了避免长时间保持连接,确保在连接字符串中添加Pooling=false来禁用ADO.NET连接池

using (var conn = new SqlConnection("Data Source=server;Initial Catalog=somedb;User Id=foo;Password=secret;Pooling=false"))
using (var cmd = conn.CreateCommand())
{
    conn.Open();
    cmd.CommandText = "DELETE FROM foo";
    var result = cmd.ExecuteNonQuery();
}

吹毛求疵:据我所知,Windows 没有进程分叉的过程。 - Sebastian Mach

0

我认为SqlCommand是一个明显的赢家,因为您不需要连接不同的进程。完成后,您可以立即关闭数据库连接。

然后,您还可以将应用程序分发到没有可用“sqlcmd”的机器上。


0

我认为SqlCommand是一个不错的选择,但请记住,这个类只适用于连接SQL Server。如果你要处理Oracle或其他数据库的OleDb连接,你需要其他类型的Command/Connection类。所有数据命令对象都继承自DbCommand,所以我建议你先了解一下它。


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