Как преобразовать функцию SQL SERVER в ПРОЦЕДУРУ - PullRequest
0 голосов
/ 30 января 2020

У меня есть таблица данных следующим образом:

TreeTable

+----+--------------+---------------------------+
| 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
...