Как РАСПЕЧАТАТЬ сообщение от функции CLR SQL?

Говорят, что массивы «распадаются» на указатели. Массив C ++, объявленный как int numbers [5], не может быть перенаправлен, т. Е. Вы не можете сказать numbers = 0x5a5aff23. Что еще более важно, термин «распад» означает потерю типа и размерности; numbers распадаются на int*, теряя информацию о размерности (число 5), и тип больше не int [5]. Посмотрите здесь случаи, когда распад не происходит .

Если вы передаете массив по значению, то, что вы действительно делаете, это копирование указателя - указатель на первый элемент массива копируется в параметр (тип которого также должен быть указателем типа элемента массива). Это работает из-за разлагающейся природы массива; после разложения sizeof больше не дает полный размер массива, поскольку он по существу становится указателем. Именно поэтому предпочтительнее (среди других причин) проходить по ссылке или указателю.

Три способа передачи в массиве 1:

void by_value(const T* array)   // const T array[] means the same
void by_pointer(const T (*array)[U])
void by_reference(const T (&array)[U])

Последние два будут давать правильный sizeof, в то время как первый не будет, так как аргумент массива распался для назначения параметру.

1 Константа U должна быть известна во время компиляции.

32
задан Cade Roux 29 January 2009 в 19:18
поделиться

3 ответа

Ответ заключается в том, что вы не можете выполнить эквивалент

PRINT 'Hello World'

изнутри [SqlFunction ()] . Однако вы можете сделать это из [SqlProcedure ()] , используя

SqlContext.Pipe.Send("hello world")

. Это согласуется с T-SQL, где вы получите сообщение об ошибке «Недопустимое использование побочного оператора PRINT» в function ", если вы вставите PRINT в функцию. Но только не, если вы делаете это из хранимой процедуры.

В качестве обходного пути я предлагаю:

  1. Используйте Debug.Print из вашего кода и прикрепите отладчик к SQL Server (я знаю, что это не работает для вас, как вы объяснили).
  2. Сохраните сообщения в глобальной переменной, например List messages , и напишите другую возвращающую табличное значение функцию, которая возвращает содержимое сообщений . Конечно, доступ к сообщениям необходимо синхронизировать, потому что несколько потоков могут попытаться получить к нему доступ одновременно.
  3. Переместите свой код в [SqlProcedure ()]
  4. Добавьте параметр ' debug ', что при = 1 функция будет возвращать сообщения как часть возвращаемой таблицы (при условии, что есть столбец с текстом ..)
31
ответ дан 27 November 2019 в 21:00
поделиться

Ahh я вижу... Jsut для разъяснения: если Вы имеете SqlFunction затем SqlContext. Канал не доступен, однако в SqlProcedure это, и можно использовать, Отправляют () для записи сообщений.

я все еще не нашел путь к выходной информации от SqlFunction кроме сообщения об исключении.

2
ответ дан 27 November 2019 в 21:00
поделиться

Необходимо просто смочь сделать:

SqlContext.Pipe.Send("hello world");

, Если Вы работаете, это в UDF CLR, SqlContext.Pipe всегда будет null, когда Вы обнаружили. Без допустимого SqlPipe я не полагаю, что можно сделать то, что Вы хотите.

, Если это просто для отладки целей, Вы могли бы всегда открывать файл в рамках управляемого кода и писать Ваш вывод там. Это требует той Вашей сборки, имеет EXTERNAL_ACCESS разрешение, однако, и это в свою очередь требует, чтобы база данных была отмечена как защищенная. Не обязательно что-то, что я сделал бы или рекомендовал бы.

10
ответ дан 27 November 2019 в 21:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: