Подтвердить что ты не робот

Использовать SQL для фильтрации результатов хранимой процедуры

Я рассмотрел другие вопросы о переполнении стека, связанные с этим вопросом, но никто из них, казалось, не ответил на этот вопрос четко.

У нас есть хранимая в системе процедура, называемая sp_who2, которая возвращает набор результатов для всех запущенных процессов на сервере. Я хочу отфильтровать данные, возвращаемые хранимой процедурой; концептуально, я мог бы сделать это так:

SELECT * FROM sp_who2
WHERE login='bmccormack'

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

4b9b3361

Ответ 1

Нет хороших способов сделать это. Это ограничение хранимых процедур. Ваши варианты:

  • Переключите процедуру в Пользовательская функция. Во всем мире сегодня люди создают хранимые процедуры, которые должны быть функциями. Это вопрос образования. Вы, например, хороший пример. Если ваша процедура была вместо UDF, вы могли бы просто сделать следующее, точно так же, как вы интуитивно думаете, что сможете:

    SELECT * FROM udf_who2()
    WHERE login='bmccormack'
    
  • Если вы действительно не можете прикоснуться к своей процедуре, и должен сделать это в sql, тогда вам придется напугать. Сделайте еще одну хранимую процедуру, чтобы обернуть оригинальную процедуру. Внутри вашей новой процедуры вызовите существующую процедуру и поместите значения во временную таблицу, затем выполните запрос к этой таблице с нужным фильтром и верните этот результат во внешний мир.

Начиная с SQL Server 2005, определенные пользователем функции - это то, как вы инкапсулируете извлечение данных. Хранимые процедуры вместе с представлениями являются специальными инструментами для использования в конкретных ситуациях. Они оба очень удобны в нужное время, но не первый выбор. Некоторые могут подумать, что приведенный выше пример (A) получает все результаты функции, а затем (B) фильтры на этом наборе результатов, например, в подзапрос. Это не тот случай. SQL Server 2005+ оптимизирует этот запрос; если на login есть индекс, вы не видите сканирование таблицы в плане выполнения запроса; очень эффективен.

Изменить. Я должен добавить, что внутренности UDF подобны внутренним свойствам SP. Если он возится с логикой SP, которую вы хотите избежать, вы все равно можете изменить его на функцию. Несколько раз я делал большой, страшный код процедур, который я не хотел понимать, и успешно передал его функции. Единственная проблема будет заключаться в том, что процедура изменяет что-либо в дополнение к возврату результатов; UDF не могут изменять данные в db.

Ответ 2

Вы можете сделать OPENROWSET(), но есть некоторые проблемы безопасности/производительности.

SELECT * 
FROM OPENROWSET ('SQLOLEDB', 'Server=(local);TRUSTED_CONNECTION=YES;', 'exec mystoredproc')

Традиционно добавление его к переменной temp/table будет работать.

Ответ 3

Фильтрация временной таблицы является возможным способом.

-- Create tmp table from sp_who results
CREATE TABLE #TmpWho
(spid INT, ecid INT, status VARCHAR(150), loginame VARCHAR(150),
hostname VARCHAR(150), blk INT, dbname VARCHAR(150), cmd VARCHAR(150), request_id INT)
INSERT INTO #TmpWho
EXEC sp_who

-- filter temp table where spid is 52
SELECT * FROM #TmpWho
WHERE spid = 52

DROP TABLE #TmpWho

Ответ 4

Поместите данные в Табличную переменную или таблицу Temp и фильтруйте на ней.