У меня есть таблица данных следующим образом:
+----+--------------+---------------------------+
| Id | Pid | Title |
+----+--------------+---------------------------+
| 1 | 0 | System |
| 2 | 1 | Setting |
| 3 | 1 | DataSource |
| 4 | 2 | Models |
| 5 | 4 | Users |
| 7 | 4 | Factory |
+----+--------------+---------------------------+
Я закончил функцию для генерации иерархического json из данных следующим образом: но я не знаю, как преобразовать его в процедуру, чтобы использовать динамическое c имя таблицы:
CREATE FUNCTION TreeJson(@Id INT, @IsRoot INT)
RETURNS NVARCHAR(MAX)
BEGIN
DECLARE @Json NVARCHAR(MAX) = '{}', @Root NVARCHAR(MAX)
SET @Json = (SELECT *, JSON_QUERY(dbo.TreeJson(Id, 2) ) AS Children FROM dbo.TreeTable WHERE Pid = @Id FOR JSON AUTO);
IF(@IsRoot = 1)
BEGIN
SET @Root = (select * FROM dbo.TreeTable WHERE Id = @Id FOR JSON PATH, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER)
SET @Json = JSON_MODIFY(@Root, '$.Children', JSON_QUERY(@Json))
SET @IsRoot = 2
END
RETURN @Json
END
Я пытаюсь преобразовать в процедуру следующим образом, но не могу получить правильные данные:
CREATE PROCEDURE SelectTree
@Table sysname,
@Id BIGINT,
@IsRoot INT,
@OutJson NVARCHAR(MAX) OUTPUT
AS
BEGIN
DECLARE @Json NVARCHAR(MAX) = '{}',@Children NVARCHAR(MAX), @Root NVARCHAR(MAX), @Sql NVARCHAR(MAX), @TmpJson NVARCHAR(MAX), @CurId BIGINT
DECLARE @ChildTable TABLE([Id] BIGINT)
SET @Sql = 'Select Id from ' + quotename(@Table) + ' WHERE Pid = ' + cast(@Id as nvarchar);
Insert into @ChildTable exec(@Sql);
DECLARE rs CURSOR LOCAL SCROLL FOR (select distinct Id from @ChildTable)
open rs
fetch next from rs into @CurId;
while @@FETCH_STATUS = 0
begin
EXEC SelectTree @Table, @CurId, 2, @TmpJson OUTPUT;
SET @Sql = 'select @Json = (SELECT *, JSON_QUERY(@TmpJson) AS Children FROM ' + quotename(@Table) + ' WHERE Pid = @Id FOR JSON AUTO)';
EXEC sp_executesql @Sql, N'@Json NVARCHAR(MAX) output, @TmpJson NVARCHAR(MAX), @Id BIGINT', @Json output, @TmpJson, @CurId;
fetch next from rs into @CurId;
end
close rs
deallocate rs
IF(@IsRoot = 1)
BEGIN
SET @Sql = 'Select @Root = (select * FROM ' + quotename(@Table) + ' WHERE Id = @Id FOR JSON PATH, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER)';
EXEC sp_executesql @Sql, N'@Root NVARCHAR(MAX) output, @Id BIGINT', @Root output, @Id;
SET @Json = JSON_MODIFY(@Root, '$.Children', JSON_QUERY(@Json));
SET @IsRoot = 2
END
SET @OutJson = @Json;
END