Parameter Table-Valued sebagai parameter Output untuk prosedur tersimpan

33

Apakah mungkin untuk parameter Table-Valued digunakan sebagai parameter output untuk prosedur tersimpan?

Inilah yang ingin saya lakukan dalam kode

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

Jawaban:

1

Ini adalah posting yang lebih tua, tetapi berada di dekat bagian atas ketika saya sedang mencari "Parameter Table-Valued sebagai parameter Output untuk prosedur tersimpan". Meskipun menurut pemahaman saya bahwa Anda tidak dapat melewatkan parameter bernilai tabel sebagai parameter output, saya akan membayangkan tujuannya adalah untuk menggunakan parameter output bernilai tabel sebagai parameter input bernilai tabel dalam prosedur lain. Saya akan menunjukkan contoh bagaimana saya membuat ini bekerja.

Pertama, buat beberapa data untuk digunakan:

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

Selanjutnya, buat prosedur tersimpan untuk mengambil beberapa data. Biasanya, ini akan menjadi tempat Anda mencoba membuat parameter output bernilai tabel.

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

Selain itu, Anda akan ingin membuat tipe data (tipe tabel) di mana data dari prosedur tersimpan pertama dapat dilewatkan sebagai parameter input untuk prosedur tersimpan berikutnya.

create type tblType as Table (id int)

Selanjutnya, buat prosedur tersimpan kedua yang akan menerima parameter bernilai tabel.

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

Memang, ini bukan parameter output bernilai tabel yang sebenarnya, tetapi kemungkinan akan menghasilkan hasil yang mirip dengan apa yang Anda cari. Deklarasikan parameter bernilai tabel Anda, isi dengan data dengan menjalankan prosedur yang tersimpan di dalamnya, lalu gunakan sebagai variabel input untuk prosedur selanjutnya.

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

selain jawaban yang dimasukkan dengan baik oleh remus termasuk tautan yang dia berikan

Cara Berbagi Data di antara Prosedur yang Disimpan

ada situasi di mana Anda mendapatkan pesan galat berikut saat menyimpan hasil dari prosedur tersimpan ke tabel:

Pernyataan INSERT EXEC tidak dapat disarangkan.

Transaksi saat ini tidak dapat dilakukan dan tidak dapat mendukung operasi yang menulis ke file log. Kembalikan transaksi

dan ketika ini terjadi pada prosedur tersimpan saya sendiri yang saya kembangkan untuk saya gunakan sendiri

misalnya alat untuk memberi tahu saya dari loginsemua grup AD yang dimilikinya dan semua izin mereka di semua basis data di server

Saya membuat tabel temp di luar prosedur dan memberikan namanya sebagai parameter

--===============
-- 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

dan di dalam prosedur, setelah semua perhitungan, ketika saya mengembalikan data akhir (di bawah contoh) saya memeriksa apakah kita mengeluarkan ke tabel atau hanya kembali ke layar dan membuat skrip secara dinamis.

            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)

Setelah itu Anda memiliki info yang Anda butuhkan di layar, atau jika Anda telah melewati tabel temp sebagai parameter, itu akan memiliki data sekarang.

ini adalah salah satu solusi yang saya temukan, tetapi saya hanya menggunakannya untuk pekerjaan saya sendiri DBAjika tidak, ini akan dianggap berisiko tinggi untuk Sql Injection .

Marcello Miorelli
sumber