テーブル値パラメーターをストアドプロシージャの出力パラメーターとして使用できますか?
これが、コードでやりたいことです
/*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
いいえ、残念ながらテーブル値パラメーターは読み取り専用で入力のみです。このトピックは、一般に、すべての代替手段を示す ストアドプロシージャ間でデータを共有する方法 で十分にカバーされています。私の推奨は#temp
テーブル。
これは古い投稿ですが、「ストアドプロシージャの出力パラメーターとしてのテーブル値パラメーター」を検索していたときは、一番上にありました。テーブル値パラメーターを出力パラメーターとして渡すことはできないと私は理解していますが、その目的は、そのテーブル値出力パラメーターを別の手順でテーブル値入力パラメーターとして使用することだと想像します。この作品の作り方の例を示します。
まず、使用するデータを作成します。
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' )
;
次に、一部のデータをキャプチャするストアドプロシージャを作成します。通常、これは、テーブル値の出力パラメーターを作成しようとしている場所です。
create procedure usp_OUTPUT1
@gender varchar(10)
as
Begin
select id from tbl1 where gender = @gender
End
さらに、最初のストアドプロシージャからのデータを次のストアドプロシージャの入力パラメーターとして渡すことができるデータ型(テーブル型)を作成する必要があります。
create type tblType as Table (id int)
次に、テーブル値パラメーターを受け入れる2番目のストアドプロシージャを作成します。
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
確かに、これは真のテーブル値出力パラメーターではありませんが、探しているのと同様の結果が生成される可能性があります。テーブル値パラメーターを宣言し、それにストアドプロシージャを実行してデータを入力し、次のプロシージャーの入力変数として使用します。
Declare @tblType tblType
insert into @tblType execute usp_OUTPUT1 'm'
execute usp_OUTPUT2 @tblType
加えて remusによるきれいに書かれた回答 彼が提供したリンクを含む
ストアドプロシージャの結果をテーブルに保存すると、次のエラーメッセージが表示される場合があります。
現在のトランザクションはコミットできず、ログファイルに書き込む操作をサポートできません。トランザクションをロールバックしてください
これが、自分用に開発した自分のストアドプロシージャで発生した場合
たとえば、login
から、それが属するすべてのADグループと、サーバー内のすべてのデータベース内のすべての権限から私に知らせるツール
プロシージャの外部に一時テーブルを作成し、その名前をパラメーターとして渡します
--===============
-- 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
プロシージャ内で、すべての計算の後で、最終データ(例の下)を返すときに、テーブルに出力しているか、画面に戻っているだけかを確認して、動的にスクリプトを作成します。
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)
その後、画面に必要な情報を取得するか、一時テーブルをパラメーターとして渡した場合、データが表示されます。
これは私が見つけた1つの解決策ですが、自分の作品DBA
にのみ使用します。それ以外の場合、これは Sql Injection のリスクが高いと見なされます。