Transact-SQL表值函数将调用函数的结果实现为中间表....相反,CLR表值函数表示流式替代.不要求在单个表中实现整个结果集.托管函数返回的IEnumerable对象由调用表值函数的查询的执行计划直接调用,结果以增量方式使用....如果返回的行数非常多,它也是一个更好的选择,因为它们不必在整个内存中实现.
然后我发现"填充行"方法中不允许任何数据访问.这意味着您仍然必须在init方法中执行所有数据访问并将其保留在内存中,等待调用"填充行".我误解了什么吗?如果我不将结果强制转换为数组或列表,则会出现错误:'ExecuteReader需要一个开放且可用的连接.连接的当前状态已关闭.
代码示例:
[<SqlFunction(DataAccess = DataAccessKind.Read, FillRowMethodName = "Example8Row")>]
static member InitExample8() : System.Collections.IEnumerable =
let c = cn() // opens a context connection
// I'd like to avoid forcing enumeration here:
let data = getData c |> Array.ofSeq
data :> System.Collections.IEnumerable
static member Example8Row ((obj : Object),(ssn: SqlChars byref)) =
do ssn <- new SqlChars(new SqlString(obj :?> string))
()
Run Code Online (Sandbox Code Playgroud)
我在这里处理几百万行.有没有办法懒惰地这样做?
我的问题与这个问题非常相似.
但是,我正在使用SQL Server 2005 Service Pack 2(SP2)(v9.0.3042),并且在那里发布的解决方案对我不起作用.我尝试使用两个连接字符串.一个在我的代码中被注释掉了.
我意识到我可以将所有结果存储在内存中的List或ArrayList中并返回.我已经成功完成了,但这不是目标.目标是能够在结果可用时传输结果.
这可能使用我的SQL Server版本吗?
这是我的代码:(注意,目前实际上并没有使用这些参数.我这样做是为了调试)
public static class StoredProcs
{
[SqlFunction(
DataAccess = DataAccessKind.Read,
SystemDataAccess=SystemDataAccessKind.Read,
FillRowMethodName="FillBaseline",
TableDefinition = "[baseline_id] [int], [baseline_name] [nvarchar](256), [description] [nvarchar](max), [locked] [bit]"
)]
public static IEnumerable fnGetBaselineByID(SqlString projectName, SqlInt32 baselineID)
{
string connStr = "context connection=true";
//string connStr = "data source=.;initial catalog=DBName;integrated security=SSPI;enlist=false";
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(String.Format(@"
SELECT *
FROM [DBName].[dbo].[Baseline] WITH (NOLOCK)
"), conn))
{
using (SqlDataReader …Run Code Online (Sandbox Code Playgroud)