Табличные параметры для процедур CLR в SQL Server 2008 - возможно? - PullRequest
17 голосов
/ 31 августа 2009

На этой странице из SQL Server 2008 BOL рассказывается о хранимых процедурах CLR и имеется раздел с пометкой «Табличные параметры», в котором говорится о том, как они могут быть полезными. Это здорово - я бы хотел использовать TVP в моих процессорах CLR, но, к сожалению, это единственное упоминание во вселенной о такой возможности, и в разделе не описывается, какой будет синтаксис (и при этом нет дополнительной информации ссылка в конце абзаца)

Конечно, я могу легко найти описания того, как использовать TVP из T-SQL-проков, или как делать CLR-проки в целом. Но написание процедуры CLR, которая требует TVP? Ничего такого. Все это очень необычно, поскольку передача многострочных данных в хранимый процесс является популярной проблемой.

Это заставляет меня задаться вопросом, является ли наличие раздела на этой странице ошибкой. Кто-нибудь, пожалуйста, скажите мне, что это не так, и укажите мне больше информации / примеров.

[EDIT]

Я тоже собирался опубликовать это на одном из форумов MS, когда наткнулся на это, что, кажется, последний гвоздь в гробу . Похоже, это невозможно сделать.

Ответы [ 5 ]

5 голосов
/ 31 августа 2009

Я могу найти лот еще ссылки . Однако это все для передачи табличных параметров в процедуры TSQL, так что это бесполезно.

Однако я пришел к выводу, что это невозможно. Во-первых, существует список отображений между типами CLR и SQL. Для табличных типов сопоставление отсутствует, поэтому следующее не работает, например:

[SqlProcedure]
public static void StoredProcedure(DataTable tvp, out int sum)
{
    return 42;
}

, а затем

CREATE TYPE MyTableType AS TABLE 
(
    Id INT NOT NULL PRIMARY KEY,
    [Count] INT NOT NULL
)
GO
CREATE ASSEMBLY ClrTest FROM '<somePath>'
GO
CREATE PROCEDURE ClrTest
AS EXTERNAL NAME ClrTest.StoredProcedures.StoredProcedure
GO

Какой бы тип вы ни использовали (DataTable, DbDataReader, IEnumerable), вызов CREATE PROCEDURE продолжает генерировать ошибку 6552: CREATE PROCEDURE для "ClrTest" не выполнен, поскольку типы T-SQL и CLR для параметр "@tvp" не совпадает.

Во-вторых, документация на странице, на которую вы ссылаетесь, гласит: Пользовательский тип таблицы не может быть передан в качестве табличного параметра или возвращен из управляемой хранимой процедуры или функции, выполняемой в SQL. Серверный процесс.

Кажется, я нигде не могу найти, как создать пользовательский тип таблицы в C #, но это также кажется тупиком.

Может быть, вы можете задать свой вопрос где-нибудь на форуме Microsoft. Все еще странно, что они упоминают табличные параметры на странице sproc CLR, но никогда не объясняют, как это реализовать. Если вы найдете какое-либо решение, я хотел бы знать.

4 голосов
/ 04 июля 2012

Вы можете использовать временную таблицу, созданную и заполненную перед вызовом процедуры и чтением таблицы внутри процедуры clr.

2 голосов
/ 13 июля 2012

Если вы используете C # (в отличие от VB, в котором отсутствуют пользовательские итераторы), вы можете написать код ADO.NET для вызова ExecuteNonQuery () и запустить хранимую процедуру с SqlDbType.Structured параметр (т. Е. TVP).

Коллекция, переданная как значение TVP, должна реализовывать IEnumerable<SqlDataRecord>. Каждый раз, когда доходность этого IEnumerable выполняется , SqlDataRecord «строка» передается по конвейеру к параметру «таблица».

Подробнее см. в этой статье .

2 голосов
/ 24 октября 2011

Решение состоит в том, чтобы сериализовать ваши табличные данные в строку в формате Json, а затем передать строку в вашу процедуру CLR. Внутри вашего процесса или функции clr вы бы проанализировали json для объекта IEnumerable, list или tabular. Затем вы можете работать с данными так же, как и с любыми другими типами табличных данных.

Я написал несколько утилит, способных сериализовать любую таблицу SQL в строку в формате Json. Я был бы рад поделиться ими со всеми, кто предоставил свой адрес электронной почты. Фил Фактор написал хороший парсер T-SQL Json, который он назвал parseJson. Я адаптировал его решение к CLR, который работает намного быстрее. Оба принимают строку в формате Json и создают таблицу из строки. У меня также есть множество утилит Json, которые я использую как с T-SQL, так и с CLR, способными сериализировать, анализировать, вставлять, удалять и обновлять строки в формате Json, хранящиеся в столбцах sql.

1 голос
/ 22 сентября 2011

Хотя кажется, что передача таблиц непосредственно процедурам CLR в настоящее время невозможна, я получил результат, хотя и неоптимальный:

  • определение таблицы TSQL со значением UDT FooTable
  • определение функции TSQL, которая принимает FooTable в качестве параметра и возвращает XML, используя FOR XML EXPLICIT
  • передача результирующего XML в функцию / процедуру CLR вместо самой таблицы

Не идеально, но становится немного ближе.

...