SQL Server-выбор из хранимой процедуры

у меня есть хранимая процедура, которая возвращает строки:

CREATE PROCEDURE MyProc
AS
BEGIN
    SELECT * FROM MyTable
END

моя фактическая процедура немного сложнее, поэтому необходим sproc.

можно ли выбрать вывод, вызвав эту процедуру?

что-то типа:

SELECT * FROM (EXEC MyProc) AS TEMP

мне нужно использовать SELECT TOP X, ROW_NUMBER, и еще WHERE предложения на странице Мои данные, и я не хочу передавать эти значения в качестве параметров.

15 ответов


вы можете использовать пользовательская функция или посмотреть вместо процедуры.

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


вы должны смотреть на эту прекрасную статью Ерланд сайт sommarskog:

в нем в основном перечислены все доступные параметры для вашего сценария.


вы можете

  1. создайте переменную таблицы для удержания результирующего набора из хранимой proc и тогда
  2. вставить выход хранимую proc в таблице переменных, а потом ... --5-->
  3. используйте переменную таблицы точно так же, как и любой другой таблица...

... язык SQL. ...

Declare @T Table ([column definitions here])
Insert @T Exec storedProcname params 
Select * from @T Where ...

вы либо хотите табличное значение функции или вставьте EXEC во временную таблицу:

INSERT INTO #tab EXEC MyProc

вы должны прочитать о функции openrowset и функция openquery

SELECT  * 
INTO    #tmp FROM    
OPENQUERY(YOURSERVERNAME, 'EXEC MyProc @parameters')

нет необходимости использовать временную таблицу.

Это мое решение

SELECT  *  FROM    
OPENQUERY(YOURSERVERNAME, 'EXEC MyProc @parameters')
WHERE somefield = anyvalue

вы можете скопировать выходные данные из sp в таблицу temporaty.

CREATE TABLE #GetVersionValues
(
    [Index] int,
    [Name]  sysname,
    Internal_value  int,
    Character_Value sysname
)
INSERT #GetVersionValues EXEC master.dbo.xp_msver 'WindowsVersion'
SELECT * FROM #GetVersionValues
drop TABLE #GetVersionValues

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

declare @MyTableType as table
(
FIRSTCOLUMN int
,.....
)  

затем вам нужно вставить результат вашей хранимой процедуры в тип таблицы, который вы только что определили

Insert into @MyTableType 
EXEC [dbo].[MyStoredProcedure]

В конце просто выберите из своего типа таблицы

Select * from @MyTableType

используйте OPENQUERY и befor Execute set ' SET FMTONLY OFF; SET NOCOUNT ON;'

попробуйте этот код:

SELECT top(1)*
FROM
OPENQUERY( [Server], 'SET FMTONLY OFF; SET NOCOUNT ON; EXECUTE  [database].[dbo].[storedprocedure]  value,value ')

вы можете немного обмануть с OPENROWSET:

SELECT ...fieldlist...
FROM OPENROWSET('SQLNCLI', 'connection string', 'name of sp')
WHERE ...

это все равно будет запускать весь SP каждый раз, конечно.


попробуйте преобразовать процедуру в встроенную функцию, которая возвращает таблицу следующим образом:

CREATE FUNCTION MyProc()
RETURNS TABLE AS
RETURN (SELECT * FROM MyTable)

и тогда вы можете назвать его как

SELECT * FROM MyProc()

у вас также есть возможность передавать параметры функции следующим образом:

CREATE FUNCTION FuncName (@para1 para1_type, @para2 para2_type , ... ) 

и называть это

SELECT * FROM FuncName ( @para1 , @para2 )

Если' Data ACCESS ' false,

EXEC sp_serveroption 'SQLSERVERNAME', 'DATA ACCESS', TRUE

после

SELECT  *  FROM OPENQUERY(SQLSERVERNAME, 'EXEC DBNAME..MyProc @parameters')

это работает.


для простоты и чтобы сделать его повторно запускаемым, я использовал систему StoredProcedure "sp_readerrorlog" для получения данных:

-----USING Table Variable
DECLARE @tblVar TABLE (
   LogDate DATETIME,
   ProcessInfo NVARCHAR(MAX),
   [Text] NVARCHAR(MAX)
)
INSERT INTO @tblVar Exec sp_readerrorlog
SELECT LogDate as DateOccured, ProcessInfo as pInfo, [Text] as Message FROM @tblVar



-----(OR): Using Temp Table
IF OBJECT_ID('tempdb..#temp') IS NOT NULL  DROP TABLE #temp;
CREATE TABLE #temp (
   LogDate DATETIME,
   ProcessInfo NVARCHAR(55),
   Text NVARCHAR(MAX)
)
INSERT INTO #temp EXEC sp_readerrorlog
SELECT * FROM #temp

похоже, вам просто нужно использовать посмотреть. Представление позволяет представить запрос в виде таблицы, чтобы его можно было запросить.


Если ваш сервер называется SERVERX, например, вот как я это сделал...

EXEC sp_serveroption 'SERVERX', 'DATA ACCESS', TRUE;
DECLARE @CMD VARCHAR(1000);
DECLARE @StudentID CHAR(10);
SET @StudentID = 'STUDENT01';
SET @CMD = 'SELECT * FROM OPENQUERY([SERVERX], ''SET FMTONLY OFF; SET NOCOUNT ON; EXECUTE MYDATABASE.dbo.MYSTOREDPROC ' + @StudentID + ''') WHERE SOMEFIELD = SOMEVALUE';
EXEC (@CMD);

чтобы проверить, что это сработало, я прокомментировал EXEC() командной строки и заменил его на SELECT @CMD чтобы просмотреть команду, прежде чем пытаться ее выполнить! Это было сделано для того, чтобы убедиться, что все правильное количество одинарных кавычек находится в нужном месте. :-)

надеюсь, это кому-то поможет.