我的问题本质上很简单--查询一个数据库,并将输出写入一组文件(~1000)。
我有一个SQL查询需要从SQL Server上的C#执行。除了in子句中的一个值之外,查询相当简单。
例如,查询可能如下所示:
SELECT
ID, Name
FROM
MyTable
WHERE
SomeValue IN (/* list of values */)值列表大约有300个字符串,每个字符串6个字符。这些值最终将类似于("A00001“、"A00002”等),并由应用程序的用户指定为输入。
我最初的想法是将查询构建为一个长字符串,将每个值聚合在一起。然而,这似乎不是正确的方法,而且似乎很容易出错。我的下一个想法是使用存储过程,但我不确定应该如何将数据传递给它。如何以一种高效的方式构建此查询,以便可靠地传递数据?
我的另一个选择是从SQL Server读取所有数据,然后在收到结果时在C#中对其进行筛选。然而,如果我这样做,我将获得大约900万条记录,这似乎太多了,无法作为一个数据集读取到内存中。因为我是在解析大约5000条记录之后写入文件的,所以我不希望在分析接收到的数据时保持数据读取器与数据库的连接。
最好的方法是什么?
发布于 2012-01-31 03:16:25
以下是使用xml完成此操作的一种方法:
C#:
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:
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))发布于 2012-01-31 03:04:47
通常的方法是将IN子句作为子查询:
SELECT ProductID from Product where ManufacturerID in
(SELECT ManufacturerID from Manufacturer where HomeOfficeLocation = 'France')如果您不能做到这一点:只要用户从您提供的列表中进行选择,简单的连接列表就不会特别容易出错。
您肯定不希望循环遍历大型数据集来查找少量的项。
编辑以添加
说得更完整一点:我经常做的是在前端创建一个逗号分隔的列表(例如:"234, 345, 456")并将其作为字符串传递给存储过程;然后在该过程中使用用户定义函数,例如讨论的here函数。
我不反对临时表,但通常只有当我要对列表执行多个操作时才会使用临时表。
我之所以说“只要用户是从列表中挑选的”,是为了省去你验证(和清理)用户输入的麻烦。
发布于 2012-01-31 03:19:43
这个主题将在本系列文章中详细讨论:
您应该从第一篇文章使用Table Value Parameter中推荐的方法开始。另请参阅MSDN用法文章:Table-Valued Parameters in SQL Server 2008 (ADO.NET)
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() {...}
}
}https://stackoverflow.com/questions/9069250
复制相似问题