簡體   English   中英

如何從存儲過程中選擇

[英]How to SELECT FROM stored procedure

我有一個返回行的存儲過程:

CREATE PROCEDURE MyProc
AS
BEGIN
    SELECT * FROM MyTable
END

我的實際過程有點復雜,這就是為什么需要存儲過程。

是否可以通過調用此過程來選擇輸出?

就像是:

SELECT * FROM (EXEC MyProc) AS TEMP

我需要使用SELECT TOP XROW_NUMBER和一個額外的WHERE子句來分頁我的數據,我真的不想將這些值作為參數傳遞。

你可以

  1. 創建一個表變量來保存來自存儲過程的結果集,然后
  2. 將存儲過程的輸出插入到表變量中,然后
  3. 完全像使用任何其他表一樣使用表變量...

... sql ....

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

您可以使用用戶定義的函數視圖而不是過程。

一個過程可以返回多個結果集,每個結果集都有自己的模式。 它不適合在SELECT語句中使用。

你應該看看Erland Sommarskog的這篇優秀文章:

它基本上列出了您的方案的所有可用選項。

您要么想要一個表值函數,要么將您的 EXEC 插入到臨時表中:

INSERT INTO #tab EXEC MyProc

您需要聲明一個包含與您的存儲過程返回的列數相同的表類型。 表類型中列的數據類型與程序返回的列的數據類型應相同

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

然后你需要在你剛剛定義的表類型中插入你的存儲過程的結果

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

最后只需從您的表格類型中選擇

Select * from @MyTableType

你必須閱讀關於OPENROWSETOPENQUERY

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

沒有必要使用臨時表。

這是我的解決方案

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

您可以將輸出從 sp 復制到臨時表。

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

嘗試將您的過程轉換為內聯函數,該函數返回一個表,如下所示:

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 )

使用 OPENQUERY,並在執行 set SET FMTONLY OFF; SET NOCOUNT ON; SET FMTONLY OFF; SET NOCOUNT ON;

試試這個示例代碼:

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

如果您收到錯誤“服務器未配置用於數據訪問”,請使用以下命令:

EXEC sp_serveroption 'YourServer', 'DATA ACCESS', TRUE

如果“數據訪問”為假,

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

后,

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

有用。

你可以用 OPENROWSET 作弊:

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

當然,這仍然每次都會運行整個 SP。

為了簡單起見並使其可重新運行,我使用了系統 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

聽起來您可能只需要使用view 視圖允許將查詢表示為表,因此可以查詢視圖。

例如,如果您的服務器名為 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以在嘗試執行之前查看該命令! 那是為了確保所有正確數量的單引號都在正確的位置。 :-)

我希望能幫助某人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM