Tham số giá trị bảng làm tham số đầu ra cho thủ tục được lưu trữ


33

Có phải nó có khả năng tham số Bảng giá trị được sử dụng làm tham số đầu ra cho thủ tục được lưu trữ không?

Đây là những gì tôi muốn làm trong mã

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

Câu trả lời:



1

Đây là một bài viết cũ hơn, nhưng nó ở gần đầu khi tôi đang tìm kiếm "Tham số có giá trị bảng làm tham số đầu ra cho thủ tục được lưu trữ". Theo hiểu biết của tôi rằng bạn không thể truyền tham số có giá trị bảng làm tham số đầu ra, tôi sẽ tưởng tượng mục tiêu là sử dụng tham số đầu ra có giá trị bảng đó làm tham số đầu vào có giá trị bảng trong quy trình khác. Tôi sẽ đưa ra một ví dụ cho cách tôi thực hiện công việc này.

Đầu tiên, tạo một số dữ liệu để làm việc với:

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

Tiếp theo, tạo một thủ tục được lưu trữ để nắm bắt một số dữ liệu. Thông thường, đây sẽ là nơi bạn đang cố gắng tạo một tham số đầu ra có giá trị bảng.

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

Ngoài ra, bạn sẽ muốn tạo một kiểu dữ liệu (kiểu bảng) trong đó dữ liệu từ thủ tục được lưu trữ đầu tiên có thể được chuyển qua làm tham số đầu vào cho thủ tục được lưu trữ tiếp theo.

create type tblType as Table (id int)

Tiếp theo, tạo thủ tục được lưu trữ thứ hai sẽ chấp nhận tham số có giá trị bảng.

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

Cấp, đây không phải là một tham số đầu ra có giá trị bảng thực sự, nhưng nó có thể sẽ tạo ra kết quả tương tự như những gì bạn sẽ tìm kiếm. Khai báo tham số có giá trị bảng của bạn, điền dữ liệu vào nó bằng cách thực hiện thủ tục được lưu trữ vào nó, sau đó sử dụng nó làm biến đầu vào cho thủ tục tiếp theo.

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

1

ngoài câu trả lời độc đáo bằng cách nhắc lại bao gồm cả liên kết anh ấy cung cấp

Cách chia sẻ dữ liệu giữa các thủ tục lưu trữ

có những tình huống bạn nhận được các thông báo lỗi sau khi lưu kết quả của một thủ tục được lưu vào bảng:

Một câu lệnh INSERT EXEC không thể được lồng nhau.

Giao dịch hiện tại không thể được cam kết và không thể hỗ trợ các hoạt động ghi vào tệp nhật ký. Phục hồi giao dịch

và khi điều này xảy ra trên các thủ tục lưu trữ của riêng tôi mà tôi phát triển để sử dụng cho riêng mình

ví dụ một công cụ cho tôi biết từ logintất cả các nhóm AD mà nó thuộc về và tất cả các quyền của họ trong tất cả các cơ sở dữ liệu trong máy chủ

Tôi tạo một bảng tạm thời bên ngoài thủ tục và truyền tên của nó làm tham số

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

và bên trong thủ tục, sau tất cả các tính toán, khi tôi trả lại dữ liệu cuối cùng (bên dưới một ví dụ) tôi kiểm tra xem liệu chúng ta có xuất ra một bảng hay chỉ quay lại màn hình và tạo tập lệnh một cách linh hoạt.

            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)

Sau đó, bạn có thông tin bạn cần trên màn hình hoặc nếu bạn đã vượt qua bảng tạm thời làm tham số, nó sẽ có dữ liệu ngay bây giờ.

Đây là một giải pháp tôi đã tìm thấy, nhưng tôi chỉ sử dụng nó cho các công việc của riêng mình DBAnếu không điều này sẽ được coi là rủi ro cao đối với Sql Injection .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.