SQL Server CLR TVF не поддерживает многопоточность?

Относительно этого предыдущего вопроса stackru:

DRY CLR табличные функции

Кажется, он работает только в однопоточном режиме. Чтобы проверить это, я немного изменил код, добавив в поле "Имя" номер текущего потока. Всем возвращенным результатам был присвоен одинаковый номер потока. Это действие по замыслу? Есть ли способ получить многопоточность? Благодарю.

private class ResultRow
// This class holds a row which we want to return.
{
    public SqlInt32 CustId;
    public SqlString Name;

    public ResultRow(SqlInt32 custId_, SqlString name_)
    {

        int mythread = Thread.CurrentThread.ManagedThreadId;
        CustId = custId_;
        Name = "[" + mythread.ToString() + "] " + name_;
    }
}

РЕДАКТОР за вопрос Марка:

Вот полный кусок кода. Возвращает 3470 записей за 7 секунд.

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Runtime.InteropServices;
using System.Text;
using System.Collections.Generic;
using System.Collections;
using System.Threading;

namespace CS_CLR_TVF
{

  public partial class UserDefinedFunctions
  {

    // This class holds a row which we want to return.
    private class ResultRow
    {
        public SqlString fldProductName;
        public ResultRow(SqlString product_)
        {
            int mythread = Thread.CurrentThread.ManagedThreadId;
            fldProductName = "[" + mythread.ToString() + "] " + product_;
        }
    }

    [SqlFunction(DataAccess = DataAccessKind.Read, FillRowMethodName = "Test_FillRow", TableDefinition = "fldProductName nvarchar(1024)")]
    public static IEnumerable xudf_cs_tvf(SqlString strSearchClue)
    {
        ArrayList results = new ArrayList();

        using (SqlConnection connection = new SqlConnection("context connection=true"))
        {
            connection.Open();
            string s1;

            using (SqlCommand select = new SqlCommand("SELECT fldProductName FROM tblProducts", connection))
            {
                using (SqlDataReader reader = select.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        s1 = reader.GetSqlString(0).ToString();

                        // do a substring compare, if "match" grab the row
                        int idx = s1.IndexOf(strSearchClue.ToString());
                        if (idx > -1) results.Add(new ResultRow(reader.GetSqlString(0)));
                    }
                }
            }
        }
        return results;
    }

    // This function takes a row and tells SQL Server what variables we want to 
    // return from it and what types it contains.
    public static void Test_FillRow(object resultsObj, out SqlString fldProductName)
    {
        ResultRow selectResults = (ResultRow)resultsObj;
        fldProductName = selectResults.fldProductName;
    }
  }
}

Довольно прямолинейное внутреннее утверждение выбора:

SELECT fldProductName FROM tblProducts

,,,, Вот версия, реализованная в виде скалярного UDF, и она выполняет многопоточность. Возвращает 3470 записей за <1 секунду.

[Microsoft.SqlServer.Server.SqlFunction]
public static long xudf_csfake(SqlString strSearchClue, SqlString strStringtoSearch)
{
    string s1 = strStringtoSearch.ToString();
    // do a substring compare, if "match" grab the row
    int idx = s1.IndexOf(strSearchClue.ToString());
    if (idx > -1) return 1;

    return 0;
}  

Вот это внешнее выражение выбора:

SELECT  fldProductName FROM tblProducts  WHERE (dbo.xudf_csfake('METAL' ,fldProductName) = 1)

Так что я, кажется, получаю противоположность тому, что указано в статье.

0 ответов

Другие вопросы по тегам