it-swarm-eu.dev

Parametr s hodnotou tabulky jako výstupní parametr pro uloženou proceduru

Je možné, aby byl parametr s hodnotou tabulky použit jako výstupní parametr pro uloženou proceduru?

Tady je to, co chci dělat v kódu

/*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
33
adopilot

Ne, bohužel parametry parametrů tabulky jsou pouze pro čtení a vstupy. Toto téma je obecně velmi dobře obsaženo v Jak sdílet data mezi uloženými procedurami , který představuje všechny alternativy. Mé doporučení by bylo použít #temp stůl.

36
Remus Rusanu

Toto je starší příspěvek, ale byl jsem blízko vrcholu, když jsem hledal "Tabulka-Valued Parameter jako výstupní parametr pro uloženou proceduru". I když chápu, že nemůžete předat parametr s hodnotou tabulky jako výstupní parametr, představuji si, že cílem je použít tento výstupní parametr s hodnotou tabulky jako vstupní parametr s hodnotou tabulky v jiném postupu. Ukážu příklad toho, jak jsem tuto práci provedl.

Nejprve vytvořte některá data, se kterými budete pracovat:

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'   )
;

Dále vytvořte uloženou proceduru pro zachycení některých dat. Normálně by to bylo místo, kde se pokoušíte vytvořit výstupní parametr s hodnotou tabulky.

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

Dále budete chtít vytvořit datový typ (typ tabulky), kde lze data z první uložené procedury předat jako vstupní parametr pro další uloženou proceduru.

create type tblType as Table (id int)

Dále vytvořte druhou uloženou proceduru, která bude akceptovat parametr s hodnotou tabulky.

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

Je pravda, že se nejedná o skutečný výstupní parametr s hodnotou tabulky, ale pravděpodobně povede k podobným výsledkům, jaké byste hledali. Deklarujte svůj parametr s hodnotou tabulky, vyplňte jej daty provedením uložené procedury a poté jej použijte jako vstupní proměnnou pro další postup.

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

kromě pěkně vložená odpověď remusem včetně odkazu, který poskytl

Jak sdílet data mezi uloženými procedurami

jsou situace, kdy se při ukládání výsledků uložené procedury do tabulky zobrazí následující chybová zpráva:

Příkaz INSERT EXEC nelze vnořit.

Aktuální transakce nemůže být potvrzena a nemůže podporovat operace, které zapisují do souboru protokolu. Vrácení transakce

a když k tomu dojde na vlastních uložených procedurách, které vyvíjím pro své vlastní použití

například nástroj, který mi řekne z login všech AD skupin, ke kterým patří, a všechna jejich oprávnění ve všech databázích na serveru

Mimo proceduru vytvořím dočasnou tabulku a její parametr předám 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 uvnitř procedury, po všech výpočtech, když vracím konečná data (pod příkladem), zkontroluji, zda vystupujeme do tabulky nebo jen zpět na obrazovku a dynamicky vytváříme skript.

            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)

Poté máte na obrazovce buď informace, které potřebujete, nebo pokud jste jako parametr předali dočasnou tabulku, budou mít nyní data.

toto je jedno řešení, které jsem našel, ale používám ho pouze pro vlastní díla DBA jinak to bude považováno za vysoké riziko pro Sql Injection .

1