SQL Server-SELECT FROM 저장 프로 시저


334

행을 반환하는 저장 프로 시저가 있습니다.

CREATE PROCEDURE MyProc
AS
BEGIN
    SELECT * FROM MyTable
END

내 실제 절차는 조금 더 복잡하므로 sproc이 필요합니다.

이 절차를 호출하여 출력을 선택할 수 있습니까?

다음과 같은 것 :

SELECT * FROM (EXEC MyProc) AS TEMP

데이터를 페이징 하기 위해 SELECT TOP X, ROW_NUMBER및 추가 WHERE절 을 사용해야 하며 실제로 이러한 값을 매개 변수로 전달하고 싶지 않습니다.


프로 시저를 실행할 때 행을 다시 가져 오기 때문에 여기서 무엇을 하려는지 잘 모르겠습니다. SELECT 문 내에서 프로 시저를 실행하여 페이징 가능한 개체에 연결할 수 있습니까?
Raj 더 많은

1
값을 매개 변수로 전달하지 않으려는 특별한 이유가 있습니까? 제안하는 방식이 약간 비효율적입니다. 필요한 것보다 많은 데이터를 선택한 다음 모두 사용하지는 않을 것입니다.
Mark Bell

2
여기를보십시오 : sommarskog.se/share_data.html
pylover

답변:


149

프로 시저 대신 사용자 정의 함수 또는 보기 를 사용할 수 있습니다 .

프로시 저는 각각 고유 한 스키마가있는 여러 결과 세트를 리턴 할 수 있습니다. SELECT명세서 에 사용하기에 적합하지 않습니다 .


8
또한 UDF로 변환 한 후 스토어드 프로 시저 시맨틱이 필요한 경우 항상 프로 시저로 UDF를 랩핑 할 수 있습니다.
Joel Coehoorn

여러 저장 프로 시저에 매개 변수를 보내고 하나의 큰 저장 프로 시저로 결합해야하는 경우 어떻게해야합니까? 저장 프로 시저처럼 매개 변수를보고, 취할 수 있습니다
mrN

3
@mrN Views는 매개 변수를 사용하지 않지만 UDF는 매개 변수를 사용합니다.
Mehrdad Afshari

3
안녕하세요, sp를 뷰 또는 함수로 변환하지 않고이 작업을 수행해야합니다. 가능합니까?
Luis Becerril

2
당신의 대답은 진실한 진술이지만 질문에 대답하지는 않습니다. ... "저장된 프로 시저에서 선택"이상적이지는 않지만 확실합니다 ... @Aamir의 대답은 정답입니다. 그 또는 질문이 변경되어야합니다 ... 그것은 나에게 약간 우스운 것 같습니다.
Urasquirrel

202

당신은 할 수 있습니다

  1. 저장된 proc에서 결과 세트를 보유 할 테이블 변수를 작성한 후
  2. 저장된 proc의 출력을 테이블 변수에 삽입 한 다음
  3. 다른 테이블과 마찬가지로 테이블 변수를 사용하십시오 ...

... sql ....

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

34
INSERT #T또는 의 문제 INSERT @TINSERT EXEC명령문을 중첩 할 수 없다는 것입니다. 저장 프로 시저에 이미 포함되어 있으면 INSERT EXEC작동하지 않습니다.
MOHCTP

2
이것은 아마도 가장 이식성이 뛰어난 솔루션이며 기본 SQL에 가장 가깝습니다. 또한 강력한 열 유형 정의를 유지하는 데 도움이됩니다. 위의 것보다 더 많은 투표를해야합니다.

테이블 변수는 SP의 재 컴파일의 측면에서 임시 테이블보다 여기에 더 유용 보인다. 따라서이 답변에는 더 많은 투표가 있어야합니다.
resnyanskiy

76

당신도 찾는 테이블 반환 함수를 또는 임시 테이블로 EXEC를 삽입 :

INSERT INTO #tab EXEC MyProc

32
INSERT #T또는 의 문제 INSERT @TINSERT EXEC명령문을 중첩 할 수 없다는 것입니다. 저장 프로 시저에 이미 포함되어 있으면 INSERT EXEC작동하지 않습니다.
MOHCTP

46

OPENROWSETOPENQUERY 에 대해 읽어야합니다.

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

4
YOURSERVERNAME을 동적으로 얻는 방법? 항상 알 필요는 없습니다. 매주 화요일마다 휴식이되지 않습니까? 이름이 다른 100 대의 서버가 모두 있다면
Urasquirrel

또한 내 데이터베이스가 이것을 허용하도록 구성되어 있지 않으면 어떻게해야합니까?
Urasquirrel 2016 년

4
동적으로 얻으려면 @@ servername을 시도하십시오
Siddhartha Gandhi

44

스토어드 프로 시저가 리턴하는 동일한 수의 컬럼을 포함하는 테이블 유형을 선언해야합니다. 테이블 유형의 컬럼 데이터 유형과 프로 시저가 리턴 한 컬럼은 동일해야합니다.

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

그런 다음 방금 정의한 테이블 유형에 스토어드 프로 시저 결과를 삽입해야합니다.

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

결국 테이블 유형에서 선택하십시오.

Select * from @MyTableType

서버 이름, 연결 문자열을 지정하거나 연결된 서버를 구성하기 위해 서버를 구성해야 할 필요가 없기 때문에 이것이 최선의 해결책입니다. 다시 일부 데이터. 감사합니다! 대단한 답변!
Matt

좋은 답변 ღ❤ ೋ ღ❤ღ ೋ❤ ღ
Nahid

저장 프로 시저가 너무 까다로운 경우 (예 : 저장 프로 시저가 두 개의 임시 테이블을 사용하는 경우)이 방법이 작동하지 않습니다.
nick_n_a

34

임시 테이블을 사용할 필요는 없습니다.

이것은 나의 해결책이다

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

2
이를 위해서는 서버를 연결된 서버로 추가해야하지만 매력처럼 작동합니다! 감사!
vaheeds

이것에 대한 몇 가지주의 사항 : stackoverflow.com/questions/2374741/…
Keith Adler

1
흠 ... "오류 7411 : 서버 'YourServerName'이 (가) DATA ACCESS로 구성되지 않았습니다."오류가 발생합니다. 무엇을 변경해야합니까?
Matt

서버를 연결된 서버로 추가 했습니까? YourServerName은 서버 이름입니다. 실제 서버 이름으로 YourServerName을 변경해야합니다.
DavideDM

@ 매트 :sp_serveroption 'MYSERVER', 'DATA ACCESS', TRUE;
alexkovelsky

23

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

7

OPENQUERY를 사용하고 set 'SET FMTONLY OFF'를 실행하십시오. 설정 NOCOUNT ON; '

이 샘플 코드를 사용해보십시오 :

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

6

프로 시저를 다음과 같이 테이블을 리턴하는 인라인 함수로 변환하십시오.

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 )

6

'DATA ACCESS'가 거짓이면

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

후,

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

효과가있다.


5

OPENROWSET으로 약간의 부정 행위를 할 수 있습니다 :

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

물론 이것은 항상 전체 SP를 실행합니다.


4

간단하게하기 위해 다시 실행할 수 있도록하기 위해 시스템 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


1

예를 들어 서버의 이름이 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 을 실행하기 전에 했습니다! 그것은 올바른 수의 모든 작은 따옴표가 올바른 위치에 있는지 확인하는 것이 었습니다. :-)

누군가에게 도움이되기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.