У меня есть хранимая процедура в моей базе данных SQL Server 2017, которая используется node.js API. Эта хранимая процедура выполняет некоторые вычисления, а затем возвращает объект json с использованием FOR JSON PATH
.
Теперь я хочу написать несколько тестов в T- SQL, чтобы гарантировать правильное функционирование этой хранимой процедуры. Изменение хранимой процедуры невозможно.
Чтобы воспроизвести проблему, предположим, что у меня есть такая хранимая процедура:
USE tempdb
GO
CREATE PROCEDURE dbo.example_sp
AS
BEGIN
SELECT val1, val2
INTO #tmp
FROM ( VALUES (1, 2), (3, 4)) vals (val1, val2)
SELECT *
FROM #tmp
FOR JSON PATH
END
Теперь, отмечая, что функция FOR JSON PATH
приведет к одна ячейка (1 строка, 1 столбец) типа nvarchar
, я хотел бы сделать что-то вроде этого, чтобы извлечь объект JSON, чтобы проверить его:
CREATE TABLE #result (json_object varchar(max))
INSERT INTO #result
EXEC dbo.example_sp
Но это дает error:
Предложение FOR JSON не допускается в инструкции INSERT.
Хорошо, это расстраивает, но я могу использовать для этого работу openrowset, правильно?
INSERT INTO #result
SELECT *
FROM OPENROWSET('sqlncli', 'Server=(local);Trusted_Connection=yes;',
'EXEC tempdb.dbo.example_sp')
Нет, теперь у меня новая ошибка:
Метаданные не могут быть определены из-за оператора 'Select * from #tmp FOR JSON PATH' в процедуре example_sp используется временная таблица.
Еще более неприятно, но, конечно, я могу использовать трюк WITH RESULT SET, чтобы решить эту проблему?
INSERT INTO #result
SELECT *
FROM OPENROWSET('sqlncli', 'Server=(local);Trusted_Connection=yes;',
'EXEC tempdb.dbo.example_sp with result sets ((output varchar(max) NULL))')
Теперь я получаю это ошибка:
Невозможно обработать объект «exe c tempdb.dbo.example_sp с наборами результатов ((output varchar (max) NULL)) ". Поставщик OLE DB «SQLNCLI11» для связанного сервера «(null)» указывает, что либо у объекта нет столбцов, либо у текущего пользователя нет разрешений на этот объект.
Хорошо, чтобы разобраться с этим мы должны использовать SET NOCOUNT ON, что позволяет серверу SQL пропускать некоторую проверку. Окончательная версия:
INSERT INTO #result
SELECT *
FROM OPENROWSET('sqlncli','Server=(local);Trusted_Connection=yes;',
'SET NOCOUNT ON; exec tempdb.dbo.example_sp with result sets (( output varchar(max) NULL))')
Что в итоге работает. Я чувствую, что это слишком много для такой простой вещи ... неужели есть способ сделать это лучше?