TSQL Оценка выражений в таблице объединенных строк - PullRequest
0 голосов
/ 12 июня 2018

У меня есть таблица с построенными строками, как показано ниже.Есть ли способ выполнить каждую созданную строку и сохранить результат в другом поле в строке?

    ROW 1 'SELECT NAME FROM  ZC_ETHNIC_GROUP WHERE INTERNAL_ID = 4'
    ROW 2 'SELECT NAME FROM  ZC_LANGUAGE WHERE INTERNAL_ID = 1'
    ROW 3 'SELECT NAME FROM  ZC_PATIENT_RACE WHERE INTERNAL_ID = 8'
    ROW 4 'SELECT NAME FROM  ZC_SEX WHERE INTERNAL_ID = 1'

Ответы [ 2 ]

0 голосов
/ 12 июня 2018
declare @queries table(id int, query varchar(50), result varchar(50))

insert into @queries(id, query)
select 1, 'select 1'
union select 2, 'select 2'
union select 3, 'select 3'
union select 4, 'select 4'

declare @id int
set @id = -1

declare @query nvarchar(100)

DECLARE @tabOut AS TABLE (outVal varchar(100)) 


while(@id is not null) begin

    set @id = null
    select top 1
        @id = id,
        @query = query
    from @queries
    where result is null

    delete from @tabOut

    if (@id is not null) begin
        INSERT into @tabOut EXECUTE sp_executesql @query

        update @queries
        set result = (select top 1 outVal from @tabOut)
        where id = @id
    end;
end;

select * from @queries

Просто замените «выберите 1», «выберите 2» ... на ваши запросы.

0 голосов
/ 12 июня 2018

Вот как я бы это сделал:

DECLARE @PendingQuery TABLE
(
    ID INT NOT NULL IDENTITY(1, 1)
    ,SqlQuery NVARCHAR(MAX) NOT NULL
    ,HasBeenEvaluated BIT NOT NULL DEFAULT(0)
    ,IsEvaluationSuccess BIT NULL
    ,FailureMessage VARCHAR(255) NULL
    ,QueryResult NVARCHAR(MAX) NULL
)
--create mock data
INSERT INTO @PendingQuery(SqlQuery)
SELECT 'SELECT 1'
UNION ALL
SELECT 'SELECT NULL'
UNION ALL
SELECT 'SELECT 1=garbage'--sample invalid query with an error
--begin algorithm
DECLARE
    @ID INT
    ,@Query NVARCHAR(MAX)
    ,@IsEvaluationSuccess BIT
    ,@Error NVARCHAR(4000)
    ,@QueryResult NVARCHAR(MAX)
DECLARE EvaluationCursor CURSOR LOCAL STATIC FOR
    SELECT ID, SqlQuery
    FROM @PendingQuery
    WHERE HasBeenEvaluated = 0
OPEN EvaluationCursor
FETCH NEXT FROM EvaluationCursor INTO
    @ID
    ,@Query
WHILE @@FETCH_STATUS = 0
BEGIN
    SELECT--reset iteration variables
         @QueryResult = NULL
        ,@Error = NULL
        ,@Query = N'SELECT @QueryResult = (' + @Query + N')'

    BEGIN TRY
    BEGIN TRANSACTION
        EXEC sp_executesql
            @Query
            ,N'@QueryResult NVARCHAR(MAX) OUTPUT'
            ,@QueryResult=@QueryResult OUTPUT
        ROLLBACK--disallow data alteration
        SET @IsEvaluationSuccess = 1
    END TRY
    BEGIN CATCH
        IF @@TRANCOUNT > 0 ROLLBACK--orphaned transaction needs to be rolled back first
        SELECT
             @IsEvaluationSuccess = 0
            ,@Error = ERROR_MESSAGE()--you might want more info such as the error line
    END CATCH

    UPDATE @PendingQuery
    SET
        HasBeenEvaluated = 1
        ,IsEvaluationSuccess = @IsEvaluationSuccess
        ,FailureMessage = @Error
        ,QueryResult = @QueryResult
    WHERE ID = @ID

    FETCH NEXT FROM EvaluationCursor INTO
        @ID
        ,@Query
END
CLOSE EvaluationCursor
DEALLOCATE EvaluationCursor
--check results
SELECT * FROM @PendingQuery

Для трех примеров запросов это результат:

enter image description here

PS I действительно надеюсь, что эти запросы не сформированы из неанизированных пользовательских данных !

PPS Я не вижу никакого решения этой проблемы на основе множеств.Курсор или пользовательский цикл кажутся необходимыми.

...