Вернуть содержимое EXEC из хранимой процедуры

У меня есть следующее, которое возвращает строку, созданную EXEC в выходных данных при непосредственном запуске хранимой процедуры, но мне нужно передать эту строку обратно в вызывающую хранимую процедуру.

Эта хранимая процедура будет вызываться из основного цикла другой хранимой процедуры, и мне нужно, чтобы текст, созданный EXEC, сохранялся в переменной вызывающей процедуры.

Я раньше использовал команду EXEC sp_executesql, но не знаю, применимо ли это здесь.

Выход:

target.JOBID = source.JOBID And target.stackid = source.stackid And target.testtypeid = source.testtypeid And target.sampledparameter = source.sampledparameter And 

Completion time: 2024-06-26T16:42:29.4295301+01:00

Это хранимая процедура, которая мне нужна для возврата вывода EXEC:

ALTER PROCEDURE [dbo].[GetLinkCriteria]
    @TableName nvarchar(max)
AS
BEGIN
    SET NOCOUNT ON
    DECLARE @sql nvarchar(max);

    SET @sql = '
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ''' + @tableName + ''' AND COLUMN_NAME = ''JOBID'' )
                BEGIN SET @linkcriteria = ''target.JOBID = source.JOBID And '' END          
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ''' + @tableName + ''' AND COLUMN_NAME = ''stackid'')
                BEGIN SET @linkcriteria += ''target.stackid = source.stackid And '' END     
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ''' + @tableName + ''' AND COLUMN_NAME = ''testtypeid'')
                BEGIN SET @linkcriteria += ''target.testtypeid = source.testtypeid And '' END   
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ''' + @tableName + ''' AND COLUMN_NAME = ''colid'')
                BEGIN SET @linkcriteria += ''target.colid = source.colid And '' END
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ''' + @tableName + ''' AND COLUMN_NAME = ''runid'')
                BEGIN SET @linkcriteria += ''target.runid = source.runid And '' END
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ''' + @tableName + ''' AND COLUMN_NAME = ''lineid'')
                BEGIN SET @linkcriteria += ''target.lineid = source.lineid And '' END
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ''' + @tableName + ''' AND COLUMN_NAME = ''component'')
                BEGIN SET @linkcriteria += ''target.component = source.component And '' END
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ''' + @tableName + ''' AND COLUMN_NAME = ''sampledparameter'')
                BEGIN SET @linkcriteria += ''target.sampledparameter = source.sampledparameter And '' END
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ''' + @tableName + ''' AND COLUMN_NAME = ''parameter'')
                BEGIN SET @linkcriteria += ''target.parameter = source.parameter And '' END
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ''' + @tableName + ''' AND COLUMN_NAME = ''filename'')
                BEGIN SET @linkcriteria += ''target.filename = source.filename And '' END
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ''' + @tableName + ''' AND COLUMN_NAME = ''runtype'')
                BEGIN SET @linkcriteria += ''target.runtype = source.runtype And '' END
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ''' + @tableName + ''' AND COLUMN_NAME = ''parentmetalparameter'')
                BEGIN SET @linkcriteria += ''target.parentmetalparameter = source.parentmetalparameter And '' END
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ''' + @tableName + ''' AND COLUMN_NAME = ''metal'')
                BEGIN SET @linkcriteria += ''target.metal = source.metal And '' END
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ''' + @tableName + ''' AND COLUMN_NAME = ''gassampled'')
                BEGIN SET @linkcriteria += ''target.gassampled = source.gassampled And '' END
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ''' + @tableName + ''' AND COLUMN_NAME = ''sampledgas'')
                BEGIN SET @linkcriteria += ''target.sampledgas = source.sampledgas And '' END
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ''' + @tableName + ''' AND COLUMN_NAME = ''purpose'')
                BEGIN SET @linkcriteria += ''target.purpose = source.purpose And '' END
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ''' + @tableName + ''' AND COLUMN_NAME = ''isblank'')
                BEGIN SET @linkcriteria += ''target.isblank = source.isblank And '' END
            PRINT @linkcriteria;
            ';
    EXEC ('DECLARE @linkcriteria nvarchar(max);' + @Sql)
END

Непонятно, чего вы здесь пытаетесь достичь, но будьте осторожны: эта процедура открыта для SQL-инъекций.

Sean Lange 26.06.2024 18:35

Я создаю список назначений динамических связей таблиц, которые будут помещены в команду MERGE, которая используется для получения необработанной обновленной даты из программы C# и ее объединения с существующей базой данных. Это необходимо сделать таким образом, поскольку нет полей индекса уникального идентификатора. sql-инъекция на данный момент не является проблемой, поскольку она еще далека от реализации. Если это когда-нибудь сработает, это будет привязано когда-нибудь в будущем!

Garry_G 26.06.2024 18:47
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
57
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Как возврат значения вызывающей процедуре, так и отказ от SQL-инъекции сводятся к использованию выходных параметров как в хранимой процедуре, так и в sp_executesql. Попробуйте что-то вроде этого:

CREATE OR ALTER PROCEDURE [dbo].[GetLinkCriteria]
    @TableName nvarchar(max),
    @rv nvarchar(max) output
AS

/*
  declare @rv nvarchar(max)
  exec GetLinkCriteria @tablename='foo', @rv=@rv output
  print @rv
*/
BEGIN
    SET NOCOUNT ON
    DECLARE @sql nvarchar(max);

    SET @sql = '
            DECLARE @linkcriteria nvarchar(max) = '''';

            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName AND COLUMN_NAME = ''JOBID'' )
                BEGIN SET @linkcriteria = ''target.JOBID = source.JOBID And '' END          
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName AND COLUMN_NAME = ''stackid'')
                BEGIN SET @linkcriteria += ''target.stackid = source.stackid And '' END     
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName AND COLUMN_NAME = ''testtypeid'')
                BEGIN SET @linkcriteria += ''target.testtypeid = source.testtypeid And '' END   
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName AND COLUMN_NAME = ''colid'')
                BEGIN SET @linkcriteria += ''target.colid = source.colid And '' END
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName AND COLUMN_NAME = ''runid'')
                BEGIN SET @linkcriteria += ''target.runid = source.runid And '' END
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName AND COLUMN_NAME = ''lineid'')
                BEGIN SET @linkcriteria += ''target.lineid = source.lineid And '' END
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName AND COLUMN_NAME = ''component'')
                BEGIN SET @linkcriteria += ''target.component = source.component And '' END
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName AND COLUMN_NAME = ''sampledparameter'')
                BEGIN SET @linkcriteria += ''target.sampledparameter = source.sampledparameter And '' END
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName AND COLUMN_NAME = ''parameter'')
                BEGIN SET @linkcriteria += ''target.parameter = source.parameter And '' END
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName AND COLUMN_NAME = ''filename'')
                BEGIN SET @linkcriteria += ''target.filename = source.filename And '' END
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName AND COLUMN_NAME = ''runtype'')
                BEGIN SET @linkcriteria += ''target.runtype = source.runtype And '' END
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName AND COLUMN_NAME = ''parentmetalparameter'')
                BEGIN SET @linkcriteria += ''target.parentmetalparameter = source.parentmetalparameter And '' END
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName AND COLUMN_NAME = ''metal'')
                BEGIN SET @linkcriteria += ''target.metal = source.metal And '' END
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName AND COLUMN_NAME = ''gassampled'')
                BEGIN SET @linkcriteria += ''target.gassampled = source.gassampled And '' END
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName AND COLUMN_NAME = ''sampledgas'')
                BEGIN SET @linkcriteria += ''target.sampledgas = source.sampledgas And '' END
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName AND COLUMN_NAME = ''purpose'')
                BEGIN SET @linkcriteria += ''target.purpose = source.purpose And '' END
            IF EXISTS (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName AND COLUMN_NAME = ''isblank'')
                BEGIN SET @linkcriteria += ''target.isblank = source.isblank And '' END
            --print(@linkcriteria)
            set @rv = @linkcriteria;
            ';
    --print @sql
    EXEC sp_executesql @sql, N'@tableName nvarchar(max), @rv nvarchar(max) output', @tableName=@tableName, @rv = @rv output
END

Я внес эти изменения в процедуру GetLinkCriteria, но когда я запускаю ее напрямую, она по-прежнему отображает текст при запуске команды «exec GetLinkCriteria @tablename='StackDetails', @rv=@rv output» и ничего не показывает для «PRINT». @rv". Это означает, что когда я пытаюсь вызвать это из основной процедуры, оно сохраняет содержимое текста EXEC, а не предполагаемый результат.

Garry_G 27.06.2024 11:29

Хотя текст, внесенный в основную процедуру, соответствует моим ожиданиям.

Garry_G 27.06.2024 11:35

Я получил это на основе того, что вы сказали, спасибо.

Garry_G 27.06.2024 14:04

Я исправил это на основе того, что предоставил Дэвид. Мне просто нужно было установить возвращаемое значение «rv» в мою переменную @linkcriteria. и удалите оператор PRINT, который использовался для тестирования.

Например.

            SET @rv = @linkcriteria
            --PRINT @linkcriteria;
            ';
    EXEC sp_executesql @sql, N'@LinkTableName nvarchar(max), @rv nvarchar(max) output', @LinkTableName=@LinkTableName, @rv=@rv output

Другие вопросы по теме

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

Вызов функции в SQL Server и Oracle с одинаковым синтаксисом
Добавление столбца для оператора выбора в SQL приводит к тайм-ауту
Как рассчитать скользящую сумму для группы данных
Получите значения столбцов A таблицы 1 и значений столбца B таблицы 2 с тем же идентификатором
Как выбрать следующее наименьшее значение и следующее наибольшее значение из определенного значения записи, которое было помечено?
Аутентификация ManagedIdentityCredential недоступна. Запрошенный идентификатор не был назначен этому ресурсу
Запретить SQL сопоставлять конечные пробелы и вместо этого явно сопоставлять условие
Географическая точка внутри многоугольника показывает неверные результаты
Как вы можете вычислить, является ли результат десятичным или целым числом в SQL?
Невозможно создать DbContext типа NULL. Исключение «Ссылка на объект не установлена ​​на экземпляр объекта»