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:
в нем в основном перечислены все доступные параметры для вашего сценария.
вы можете
- создайте переменную таблицы для удержания результирующего набора из хранимой proc и тогда
- вставить выход хранимую proc в таблице переменных, а потом ... --5-->
- используйте переменную таблицы точно так же, как и любой другой таблица...
... язык 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
чтобы просмотреть команду, прежде чем пытаться ее выполнить! Это было сделано для того, чтобы убедиться, что все правильное количество одинарных кавычек находится в нужном месте. :-)
надеюсь, это кому-то поможет.