首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C#和长SQL Server查询,正确的方法是什么?

C#和长SQL Server查询,正确的方法是什么?
EN

Stack Overflow用户
提问于 2012-01-31 03:02:43
回答 6查看 5.3K关注 0票数 2

我的问题本质上很简单--查询一个数据库,并将输出写入一组文件(~1000)。

我有一个SQL查询需要从SQL Server上的C#执行。除了in子句中的一个值之外,查询相当简单。

例如,查询可能如下所示:

代码语言:javascript
运行
复制
SELECT 
    ID, Name
FROM
    MyTable
WHERE
    SomeValue IN (/* list of values */)

值列表大约有300个字符串,每个字符串6个字符。这些值最终将类似于("A00001“、"A00002”等),并由应用程序的用户指定为输入。

我最初的想法是将查询构建为一个长字符串,将每个值聚合在一起。然而,这似乎不是正确的方法,而且似乎很容易出错。我的下一个想法是使用存储过程,但我不确定应该如何将数据传递给它。如何以一种高效的方式构建此查询,以便可靠地传递数据?

我的另一个选择是从SQL Server读取所有数据,然后在收到结果时在C#中对其进行筛选。然而,如果我这样做,我将获得大约900万条记录,这似乎太多了,无法作为一个数据集读取到内存中。因为我是在解析大约5000条记录之后写入文件的,所以我不希望在分析接收到的数据时保持数据读取器与数据库的连接。

最好的方法是什么?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2012-01-31 03:16:25

以下是使用xml完成此操作的一种方法:

C#:

代码语言:javascript
运行
复制
StringBuilder sb = new StringBuilder();
sb.AppendLine("<SelectedValues>");

foreach (string s in userSelectedValues)
  sb.AppendFormat("<row val=\"{0}\" />{1}", s, Environment.NewLine);
sb.AppendLine("</SelectedValues>");

将此sb.ToString()作为XML传递给存储过程

SQL:

代码语言:javascript
运行
复制
CREATE PROCEDURE dbo.MyStoredProcedure
(
  @UserSelectedValuesXml XML
)     

SELECT * 
FROM dbo.MyTable
WHERE Id IN ( SELECT ref.value('@val', 'varchar')
              FROM @UserSelectedValuesXml.nodes('/SelectedValues/row') AS T(ref))
票数 1
EN

Stack Overflow用户

发布于 2012-01-31 03:04:47

通常的方法是将IN子句作为子查询:

代码语言:javascript
运行
复制
SELECT ProductID from Product where ManufacturerID in 
    (SELECT ManufacturerID from Manufacturer where HomeOfficeLocation = 'France')

如果您不能做到这一点:只要用户从您提供的列表中进行选择,简单的连接列表就不会特别容易出错。

您肯定不希望循环遍历大型数据集来查找少量的项。

编辑以添加

说得更完整一点:我经常做的是在前端创建一个逗号分隔的列表(例如:"234, 345, 456")并将其作为字符串传递给存储过程;然后在该过程中使用用户定义函数,例如讨论的here函数。

我不反对临时表,但通常只有当我要对列表执行多个操作时才会使用临时表。

我之所以说“只要用户是从列表中挑选的”,是为了省去你验证(和清理)用户输入的麻烦。

票数 2
EN

Stack Overflow用户

发布于 2012-01-31 03:19:43

这个主题将在本系列文章中详细讨论:

  • Arrays and Lists in SQL Server 2008 Using Table-Valued Parameters
  • Arrays and Lists in SQL Server 2005 and Beyond When TVPs Do Not Cut it
  • Arrays and Lists in SQL Server 2000 and Earlier

您应该从第一篇文章使用Table Value Parameter中推荐的方法开始。另请参阅MSDN用法文章:Table-Valued Parameters in SQL Server 2008 (ADO.NET)

代码语言:javascript
运行
复制
void SelectValuesOfInterest(IEnumerable<SqlDataRecord> valuesOfInterest)
SqlCommand cmd = new SqlCommand(@"    SELECT 
        ID, Name
    FROM
        MyTable
    WHERE
        SomeValue IN (SELECT value FROM @tableValueParameter);"
, connection);
SqlParameter tvpParam = insertCommand.Parameters.AddWithValue(
    "@tableValueParameter", valuesOfInterest);
tvpParam.SqlDbType = SqlDbType.Structured;
tvpParam.TypeName = "dbo.MyTVPType";
using (SqlDataReader rdr = cmd.ExecuteReader ())
{
 while rdr.Read() {...}
}
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9069250

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档