programing

저장 프로시저의 결과 집합에서 열 선택

mbctv 2023. 4. 6. 23:27
반응형

저장 프로시저의 결과 집합에서 열 선택

80열과 300행을 반환하는 저장 프로시저가 있습니다.나는 그 열 중 2개를 얻는 선택을 쓰고 싶다.뭐랄까

SELECT col1, col2 FROM EXEC MyStoredProc 'param1', 'param2'

위의 구문을 사용하면 다음 오류가 나타납니다.

"잘못된 열 이름"입니다.

저장 프로시저를 변경하는 것이 가장 쉬운 해결책이라는 것을 알지만, 제가 작성하지 않았기 때문에 변경할 수 없습니다.

내가 하고 싶은 일을 할 수 있는 방법이 없을까?

  • 결과를 넣을 온도표를 만들 수는 있지만, 열이 80개이기 때문에 두 열을 얻기 위해서는 80개 열의 온도표를 만들어야 합니다.반환되는 모든 열을 추적하는 것을 피하고 싶었습니다.

  • 는 는는그용사 i를 사용해 보았다.WITH SprocResults AS ....의 에러가 발생했습니다.

    'EXEC'입니다.
    '어느 쪽이든 .

  • 했습니다.

    삽입 오류: 열 이름 또는 제공된 값 수가 테이블 정의와 일치하지 않습니다.


  • SELECT * FROM EXEC MyStoredProc 'param1', 'param2'

    키워드 'exec' 근처에 구문이 잘못되었습니다.

질문을 나눠주실 수 있나요?저장된 proc 결과를 테이블 변수 또는 임시 테이블에 삽입합니다.그런 다음 표 변수에서 두 열을 선택합니다.

Declare @tablevar table(col1 col1Type,..
insert into @tablevar(col1,..) exec MyStoredProc 'param1', 'param2'

SELECT col1, col2 FROM @tablevar

다음은 문제를 해결하기 위한 다양한 방법을 설명하는 꽤 좋은 문서에 대한 링크입니다(기존 저장 프로시저를 수정할 수 없기 때문에 많은 방법을 사용할 수 없습니다).

저장 프로시저 간에 데이터를 공유하는 방법

Gulzar의 답변은 유효합니다(위 링크에 기재되어 있습니다). 그러나 @tablevar(col1,...) 스테이트먼트에 80개의 컬럼 이름을 모두 지정해야 합니다.향후 스키마에 열이 추가되거나 출력이 변경되면 코드로 업데이트해야 합니다.그렇지 않으면 오류가 발생합니다.

CREATE TABLE #Result
(
  ID int,  Name varchar(500), Revenue money
)
INSERT #Result EXEC RevenueByAdvertiser '1/1/10', '2/1/10'
SELECT * FROM #Result ORDER BY Name
DROP TABLE #Result

★★★★
http://stevesmithblog.com/blog/select-from-a-stored-procedure/httpstevesmithblog.com/blog//

은 다음과 같습니다. (30개 열중 됩니다.)sp_help_job)

SELECT name, current_execution_status 
FROM OPENQUERY (MYSERVER, 
  'EXEC msdb.dbo.sp_help_job @job_name = ''My Job'', @job_aspect = ''JOB''');  

이 작업을 수행하기 전에 다음 작업을 수행해야 했습니다.

sp_serveroption 'MYSERVER', 'DATA ACCESS', TRUE;

를 합니다.sys.servers표(즉, OPENQUERY 내 자체 참조 사용은 기본적으로 비활성화되어 있는 것 같습니다.)

간단한 요구 사항이지만, 랜스의 뛰어난 링크의 OPENQUERY 섹션에 설명된 문제는 발생하지 않았습니다.

Rossini씨, 이러한 입력 파라미터를 동적으로 설정할 필요가 있는 경우 OPENQUERY의 사용이 약간 불안정해집니다.

DECLARE @innerSql varchar(1000);
DECLARE @outerSql varchar(1000);

-- Set up the original stored proc definition.
SET @innerSql = 
'EXEC msdb.dbo.sp_help_job @job_name = '''+@param1+''', @job_aspect = N'''+@param2+'''' ;

-- Handle quotes.
SET @innerSql = REPLACE(@innerSql, '''', '''''');

-- Set up the OPENQUERY definition.
SET @outerSql = 
'SELECT name, current_execution_status 
FROM OPENQUERY (MYSERVER, ''' + @innerSql + ''');';

-- Execute.
EXEC (@outerSql);

사용의 차이점을 잘 모르겠습니다.sp_serveroption기존의 것을 갱신하다sys.servers직접 참조하는 경우가 .sp_addlinkedserver(Lance ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」

주 1: OPENQUERY가 proc 내에서 connection-string 정의를 필요로 하지 않기 때문에 OPENROWSET보다 OPENQUERY를 선호합니다.

인서트 2: 인서트하다.EXEC :) 네, 타이핑은 10분 남았습니다만, 할 수 있으면, 다음의 조작은 하고 싶지 않습니다.
의 따옴표 (a) 따옴표 안의 따옴표
tables 교활한 자기 셋업 이한 DBA (b) sys "/" Linked Server " (", ")", "DBA")

인서트하다 구성 구성)sp_help_job「INSERT EXEC」(「INSERT EXEC

(SQL Server 가정)

은 T-SQL을 하는 입니다.INSERT INTO ... EXEC구문을 사용합니다.그러면 임시 테이블 또는 테이블 변수에 삽입하고 필요한 데이터를 선택할 수 있습니다.

위해서는 '만들다'를 .#test_table음음음같 뭇매하다

create table #test_table(
    col1 int,
    col2 int,
   .
   .
   .
    col80 int
)

순서를 해 주세요.#test_table:

insert into #test_table
EXEC MyStoredProc 'param1', 'param2'

, 그럼 이 now now기서 now now now now now기 。#test_table:

select col1,col2....,col80 from #test_table

이것이 왜 그렇게 어려운지 아는 것이 도움이 될 것이다.저장 프로시저는 텍스트만 반환하거나('text' 인쇄), 여러 테이블을 반환하거나 아예 테이블을 반환하지 않을 수 있습니다.

뭐랄까...SELECT * FROM (exec sp_tables) Table1 않다

저장 프로시저를 변경할 수 있는 경우 필요한 열 정의를 쉽게 매개 변수로 지정하고 자동 생성된 임시 테이블을 사용할 수 있습니다.

CREATE PROCEDURE sp_GetDiffDataExample
      @columnsStatement NVARCHAR(MAX) -- required columns statement (e.g. "field1, field2")
AS
BEGIN
    DECLARE @query NVARCHAR(MAX)
    SET @query = N'SELECT ' + @columnsStatement + N' INTO ##TempTable FROM dbo.TestTable'
    EXEC sp_executeSql @query
    SELECT * FROM ##TempTable
    DROP TABLE ##TempTable
END

이 경우 임시 테이블을 수동으로 작성할 필요가 없습니다. 자동으로 생성됩니다.이게 도움이 됐으면 좋겠다.

은 새로운 를 추가하는 입니다.'@Column_Name'호출 함수에 취득할 컬럼 이름을 정의합니다.에는 if - all.sproc if/else if/else는 if/else로 반환됩니다.

CREATE PROCEDURE [dbo].[MySproc]
        @Column_Name AS VARCHAR(50)
AS
BEGIN
    IF (@Column_Name = 'ColumnName1')
        BEGIN
            SELECT @ColumnItem1 as 'ColumnName1'
        END
    ELSE
        BEGIN
            SELECT @ColumnItem1 as 'ColumnName1', @ColumnItem2 as 'ColumnName2', @ColumnItem3 as 'ColumnName3'
        END
END

질문에서 언급한 바와 같이 저장 프로시저를 실행하기 전에 80 컬럼의 온도 테이블을 정의하는 것은 어렵습니다.

이와는 반대로 저장 프로시저 결과 세트를 기반으로 테이블을 채웁니다.

SELECT * INTO #temp FROM OPENROWSET('SQLNCLI', 'Server=localhost;Trusted_Connection=yes;'
                                   ,'EXEC MyStoredProc')

오류가 발생하면 다음 쿼리를 실행하여 애드혹 분산 쿼리를 활성화해야 합니다.

sp_configure 'Show Advanced Options', 1
GO
RECONFIGURE
GO
sp_configure 'Ad Hoc Distributed Queries', 1
GO
RECONFIGURE
GO

sp_configure를 모두 하여 Configuration옵션을 하거나 " " "를 실행합니다.RECONFIGURE '해 주세요', '인정해 주세요', '인정해 주세요' 입니다.ALTER SETTINGSserver-level permission( 레벨 )

이제 생성된 테이블에서 특정 열을 선택할 수 있습니다.

SELECT col1, col2
FROM #temp

데이터를 수동으로 검증하기 위해 이 작업을 수행하는 경우 LINQPad를 사용하여 이 작업을 수행할 수 있습니다.

LinqPad에서 데이터베이스에 대한 연결을 만든 후 다음과 같은 C# 문을 작성합니다.

DataTable table = MyStoredProc (param1, param2).Tables[0];
(from row in table.AsEnumerable()
 select new
 {
  Col1 = row.Field<string>("col1"),
  Col2 = row.Field<string>("col2"),
 }).Dump();

레퍼런스 http://www.global-webnet.net/blogengine/post/2008/09/10/LINQPAD-Using-Stored-Procedures-Accessing-a-DataSet.aspx

SQL Server의 경우 다음 작업이 정상적으로 수행된다는 것을 알 수 있습니다.

임시 테이블(또는 영구 테이블, 실제로 중요하지 않음)을 만들고 저장 프로시저에 대해 문에 삽입을 수행합니다.SP의 결과 집합이 테이블의 열과 일치해야 합니다. 그렇지 않으면 오류가 발생합니다.

다음은 예를 제시하겠습니다.

DECLARE @temp TABLE (firstname NVARCHAR(30), lastname nvarchar(50));

INSERT INTO @temp EXEC dbo.GetPersonName @param1,@param2;
-- assumption is that dbo.GetPersonName returns a table with firstname / lastname columns

SELECT * FROM @temp;

바로 그거야!

이거 먹어봐

use mydatabase
create procedure sp_onetwothree as
select 1 as '1', 2 as '2', 3 as '3'
go
SELECT a.[1], a.[2]
FROM OPENROWSET('SQLOLEDB','myserver';'sa';'mysapass',
    'exec mydatabase.dbo.sp_onetwothree') AS a
GO

sp와 insert를 temp table 또는 table variable에 실행하는 것이 옵션인 것은 알지만, 그것이 당신의 요구사항은 아닌 것 같습니다.고객의 요건에 따라 다음 쿼리 문장이 기능합니다.

Declare @sql nvarchar(max)
Set @sql='SELECT   col1, col2 FROM OPENROWSET(''SQLNCLI'', ''Server=(local);uid=test;pwd=test'',
     ''EXEC MyStoredProc ''''param1'''', ''''param2'''''')'
 Exec(@sql)

신뢰할 수 있는 연결이 있는 경우 다음 쿼리 문을 사용합니다.

Declare @sql nvarchar(max)
Set @sql='SELECT   col1, col2 FROM OPENROWSET(''SQLNCLI'', ''Server=(local);Trusted_Connection=yes;'',
     ''EXEC MyStoredProc ''''param1'''', ''''param2'''''')'
 Exec(@sql)

위의 명령어를 실행하는데 오류가 발생할 경우 다음 명령어를 실행합니다.

sp_configure 'Show Advanced Options', 1
GO
RECONFIGURE
GO
sp_configure 'Ad Hoc Distributed Queries', 1
GO
RECONFIGURE
GO

나는 이것이 이와 같은 비슷한 문제에 직면한 사람에게 도움이 되기를 바랍니다.누군가 다음과 같은 임시 테이블 또는 테이블 변수를 사용하려고 하지만 이 시나리오에서는 sp가 반환되는 열의 수를 알아야 할 경우 임시 테이블 또는 테이블 변수에 해당 만큼의 열을 생성해야 합니다.

--for table variable 
Declare @t table(col1 col1Type, col2 col2Type)
insert into @t exec MyStoredProc 'param1', 'param2'
SELECT col1, col2 FROM @t

--for temp table
create table #t(col1 col1Type, col2 col2Type)
insert into #t exec MyStoredProc 'param1', 'param2'
SELECT col1, col2 FROM #t

간단한 답변은 다음과 같습니다.

SELECT ColA, ColB
FROM OPENROWSET('SQLNCLI','server=localhost;trusted_connection=yes;','exec schema.procedurename')

SQLNCLI는 네이티브 SQL 클라이언트이며 "localhost"를 사용하면 절차를 실행하는 서버를 사용하게 됩니다.

임시 테이블이나 다른 재즈를 만들 필요는 없습니다.

동적 뷰를 생성하여 결과를 가져옵니다.......

CREATE PROCEDURE dbo.usp_userwise_columns_value
(
    @userid BIGINT
)
AS 
BEGIN
        DECLARE @maincmd NVARCHAR(max);
        DECLARE @columnlist NVARCHAR(max);
        DECLARE @columnname VARCHAR(150);
        DECLARE @nickname VARCHAR(50);

        SET @maincmd = '';
        SET @columnname = '';
        SET @columnlist = '';
        SET @nickname = '';

        DECLARE CUR_COLUMNLIST CURSOR FAST_FORWARD
        FOR
            SELECT columnname , nickname
            FROM dbo.v_userwise_columns 
            WHERE userid = @userid

        OPEN CUR_COLUMNLIST
        IF @@ERROR <> 0
            BEGIN
                ROLLBACK
                RETURN
            END   

        FETCH NEXT FROM CUR_COLUMNLIST
        INTO @columnname, @nickname

        WHILE @@FETCH_STATUS = 0
            BEGIN
                SET @columnlist = @columnlist + @columnname + ','

                FETCH NEXT FROM CUR_COLUMNLIST
                INTO @columnname, @nickname
            END
        CLOSE CUR_COLUMNLIST
        DEALLOCATE CUR_COLUMNLIST  

        IF NOT EXISTS (SELECT * FROM sys.views WHERE name = 'v_userwise_columns_value')
            BEGIN
                SET @maincmd = 'CREATE VIEW dbo.v_userwise_columns_value AS SELECT sjoid, CONVERT(BIGINT, ' + CONVERT(VARCHAR(10), @userid) + ') as userid , ' 
                            + CHAR(39) + @nickname + CHAR(39) + ' as nickname, ' 
                            + @columnlist + ' compcode FROM dbo.SJOTran '
            END
        ELSE
            BEGIN
                SET @maincmd = 'ALTER VIEW dbo.v_userwise_columns_value AS SELECT sjoid, CONVERT(BIGINT, ' + CONVERT(VARCHAR(10), @userid) + ') as userid , ' 
                            + CHAR(39) + @nickname + CHAR(39) + ' as nickname, ' 
                            + @columnlist + ' compcode FROM dbo.SJOTran '
            END

        --PRINT @maincmd
        EXECUTE sp_executesql @maincmd
END

-----------------------------------------------
SELECT * FROM dbo.v_userwise_columns_value

이 작업을 한 번만 수행해야 하는 경우 가장 쉬운 방법:

Import and Export 마법사에서 Excel로 내보낸 다음 이 Excel을 테이블로 가져옵니다.

SQL 2012 이후를 사용하시는 분들을 위해 저는 동적이지 않고 매번 같은 컬럼을 출력하는 스토어드 프로시저를 사용하여 이 작업을 수행할 수 있었습니다.

일반적으로는 동적 쿼리를 작성하여 임시 테이블을 만들고 삽입, 선택 및 드롭하고 모두 생성된 후에 실행합니다.먼저 저장 프로시저에서 열 이름과 유형을 검색하여 동적으로 임시 테이블을 생성합니다.

주의: SP 업데이트 또는 구성 변경 및 사용을 원하는 경우 코드 줄 수를 줄여서 사용할 수 있는 훨씬 우수하고 범용적인 솔루션이 있습니다.OPENROWSET을 사용하다

DECLARE @spName VARCHAR(MAX) = 'MyStoredProc'
DECLARE @tempTableName VARCHAR(MAX) = '#tempTable'

-- might need to update this if your param value is a string and you need to escape quotes
DECLARE @insertCommand VARCHAR(MAX) = 'INSERT INTO ' + @tempTableName + ' EXEC MyStoredProc @param=value'

DECLARE @createTableCommand VARCHAR(MAX)

-- update this to select the columns you want
DECLARE @selectCommand VARCHAR(MAX) = 'SELECT col1, col2 FROM ' + @tempTableName

DECLARE @dropCommand VARCHAR(MAX) = 'DROP TABLE ' + @tempTableName

-- Generate command to create temp table
SELECT @createTableCommand = 'CREATE TABLE ' + @tempTableName + ' (' +
    STUFF
    (
        (
            SELECT ', ' + CONCAT('[', name, ']', ' ', system_type_name)
            FROM sys.dm_exec_describe_first_result_set_for_object
            (
              OBJECT_ID(@spName), 
              NULL
            )
            FOR XML PATH('')
        )
        ,1
        ,1
        ,''
    ) + ')'

EXEC( @createTableCommand + ' '+ @insertCommand + ' ' + @selectCommand + ' ' + @dropCommand)

원본 SP를 오려 붙이고 당신이 원하는 2개 열을 제외한 모든 열을 삭제합니다.또는 결과 세트를 가져와 적절한 비즈니스 객체에 매핑한 다음 LINQ를 두 열로 표시합니다.

언급URL : https://stackoverflow.com/questions/209383/select-columns-from-result-set-of-stored-procedure

반응형