Tabela wartości parametru jako parametr wyjściowy dla procedury składowanej


33

Czy jest możliwe, aby parametr Valued Table był używany jako parametr wyjściowy dla procedury składowanej?

Oto, co chcę robić w kodzie

/*First I create MY type */
CREATE TYPE typ_test AS TABLE 
(
     id int not null
    ,name varchar(50) not null
    ,value varchar(50) not null
    PRIMARY KEY (id)
)
GO


--Now I want to create stored procedu whic is going to send output type I created, 
--But it looks like it is inpossible, at least in SQL2008
create  PROCEDURE [dbo].sp_test
         @od datetime 
        ,@do datetime 
        ,@poruka varchar(Max) output
        ,@iznos money output 
        ,@racun_stavke  dbo.typ_test   READONLY --Can I Change READONLY with OUTPUT ?
AS
BEGIN
    SET NOCOUNT ON;

    /*FILL MY OUTPUT PARAMS AS I LIKE */


    end

Odpowiedzi:



1

To jest starszy post, ale był blisko szczytu, gdy szukałem „Parametru o wartości tabeli jako parametru wyjściowego dla procedury składowanej”. Chociaż rozumiem, że nie można przekazać parametru o wartości tabeli jako parametru wyjściowego, wyobrażam sobie, że celem jest użycie tego parametru o wartości tabeli jako parametru wejściowego o wartości tabeli w innej procedurze. Pokażę przykład, w jaki sposób sprawiłem, że to działa.

Najpierw utwórz dane do pracy:

create table tbl1
(
id int,
fname varchar(10),
gender varchar(10)
);
create table tbl2
(
id int,
lname varchar(10)
);
insert into tbl1
values
(1,'bob'  ,'m'),
(2,'tom'  ,'m'),
(3,'sally','f')
;
insert into tbl2
values
(1,'jones'   ),
(2,'johnson' ),
(3,'smith'   )
;

Następnie utwórz procedurę składowaną, aby przechwycić niektóre dane. Zwykle w tym miejscu próbujesz utworzyć parametr wyjściowy o wartości tabeli.

create procedure usp_OUTPUT1
 @gender varchar(10)
as
Begin
    select id from tbl1 where gender = @gender
End

Ponadto należy utworzyć typ danych (typ tabeli), w którym dane z pierwszej procedury składowanej można przekazać jako parametr wejściowy dla następnej procedury składowanej.

create type tblType as Table (id int)

Następnie utwórz drugą procedurę składowaną, która zaakceptuje parametr wyceniony w tabeli.

create procedure usp_OUTPUT2
@tblType tblType readonly  --referencing the type created and specify readonly
as
begin
 select lname from tbl2 where id in (select id from @tblType)
end

To prawda, że ​​nie jest to parametr wyjściowy wyceniony w tabeli, ale prawdopodobnie da wyniki podobne do tego, czego byś szukał. Zadeklaruj parametr wyceniony w tabeli, wypełnij go danymi, wykonując w nim procedurę przechowywaną, a następnie użyj go jako zmiennej wejściowej dla następnej procedury.

Declare @tblType tblType 
insert into @tblType execute usp_OUTPUT1 'm'
execute usp_OUTPUT2 @tblType

1

oprócz ładnie ułożonej odpowiedzi przez remus, w tym podany przez niego link

Jak udostępniać dane między przechowywanymi procedurami

istnieją sytuacje, w których podczas zapisywania wyników procedury przechowywanej w tabeli pojawiają się następujące komunikaty o błędach:

Instrukcja INSERT EXEC nie może być zagnieżdżona.

Bieżąca transakcja nie może zostać zatwierdzona i nie może obsługiwać operacji zapisujących do pliku dziennika. Cofnij transakcję

a kiedy dzieje się to na moich własnych procedur przechowywanych, które opracowuję na własny użytek

na przykład narzędzie do informowania mnie ze loginwszystkich grup AD, do których należy i wszystkich ich uprawnień we wszystkich bazach danych na serwerze

Tworzę tabelę tymczasową poza procedurą i przekazuję jej nazwę jako parametr

--===============
-- this way below it works, by passing a temp table as a parameter
--===============

                if OBJECT_ID('tempdb.dbo.#my_table') IS NOT NULL
                   DROP TABLE #my_table

                CREATE TABLE #my_table(
                    db nvarchar(128)   COLLATE Latin1_General_CI_AS  NULL,
                   permission_type nvarchar(128)   COLLATE Latin1_General_CI_AS  NULL,
                    login_  nvarchar(128)   COLLATE Latin1_General_CI_AS  NULL,
                    role_  nvarchar(128)   COLLATE Latin1_General_CI_AS  NULL,
                    Obj    nvarchar(517)   COLLATE Latin1_General_CI_AS  NULL,
                    Permission nvarchar(128)   COLLATE Latin1_General_CI_AS  NULL,
                    script nvarchar(1008)  COLLATE Latin1_General_CI_AS  NULL
                ) 

                exec sp_GetLoginDBPermissionsX 
                    @Login='my_loginname', 
                    @debug=0,
                    @where_to_save ='#my_table'

                select *
                from #my_table

a wewnątrz procedury, po wszystkich obliczeniach, kiedy zwracam ostateczne dane (poniżej przykładu) sprawdzam, czy przesyłamy dane do tabeli, czy tylko z powrotem do ekranu i dynamicznie tworzę skrypt.

            select @sql = case when @where_to_save IS not null then 
            '
            insert into ' + @where_to_save + '(db,Permission_Type,login_,role_,obj,Permission,script) '
            else '' end + 
'
        SELECT 
            J.db,
            J.Permission_Type,
            J.login_,
            J.role_,
            J.Obj,
            J.Permission,
            J.script
        FROM #tablewithpermissions J
        WHERE J.login_ IN ( SELECT  L1.LOGIN_FROM COLLATE Latin1_General_CI_AS FROM #logins L1)
           OR J.role_ IN  ( SELECT  L1.LOGIN_FROM COLLATE Latin1_General_CI_AS FROM #logins L1)
       ORDER BY J.DB, J.[permission_order]
'
        --print(@sql)

        EXEC(@SQL)

Następnie masz albo potrzebne informacje na ekranie, albo jeśli przekazałeś tabelę tymczasową jako parametr, będą one teraz mieć dane.

to jest jedno rozwiązanie, które znalazłem, ale używam go tylko do własnych prac, w DBAprzeciwnym razie będzie to uważane za wysokie ryzyko wstrzyknięcia Sql .

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.