2011-01-20 9 views
0

私は、ストアドプロシージャの入力としてテーブル変数を使用することができないことを回避するための良い作業を見つけようとしています。単一のレコードを基底テーブルに挿入し、複数のレコードをピボットテーブルに挿入したい。私の最初の思考プロセスは、ベーステーブル用に別の入力、およびピボットテーブルのレコードの単一のリスト入力、すなわちでストアドプロシージャを望むに私を導いた:すでに述べたSQL Server:ストアドプロシージャの入力テーブルの変数の回避策

create proc insertNewTask (@taskDesc varchar(100), @sTime datetime, @eTime datetime, @items table(itemID int)) 
as 
begin 
    declare @newTask table(newID int) 
    insert into tasks(description, sTimeUTC, eTimeUTC) 
    output inserted.ID into @newTask 
    values(@taskDesc, @sTime, @eTime) 

    insert into taskItems(taskID, itemID) 
    select newID, itemID 
    from @newTask cross join @items 
end 

として、上記のコードは動作しません。テーブル変数の入力のために@items(私は主に可変スコープの問題のために信じています)。だから、これにはどんな良い回避策がありますか?

元の質問
私は3つのテーブルがありますいくつかの初期アイテムデータで

CREATE TABLE items 
(
    ID   int PRIMARY KEY, 
    name  varchar(20), 
    description varchar(100) 
) 

CREATE TABLE tasks 
(
    ID   int identity(1,1) PRIMARY KEY, 
    description varchar(100), 
    sTimeUTC datetime, 
    eTimeUTC datetime 
) 

CREATE TABLE taskItems 
(
    taskID  int, 
    itemID  int, 
    CONSTRAINT fk_taskItems_taskID FOREIGN KEY (taskID) on tasks(ID), 
    CONSTRAINT fk_taskItems_itemID FOREIGN KEY (itemID) on items(ID) 
) 

insert into items (ID, name, description) 
select 1, 'nails', 'Short piece of metal, with one flat side and one pointed side' union 
select 2, 'hammer', 'Can be used to hit things, like nails' union 
select 3, 'screws', 'I''m already tired of writing descriptions for simple tools' union 
select 4, 'screwdriver', 'If you can''t tell already, this is all fake data' union 
select 5, 'AHHHHHH', 'just for good measure' 

をそして、私は新しいタスクを作成するためのいくつかのコードを持っている:

declare @taskDes varchar(100), @sTime datetime, @eTime datetime 
select @taskDes = 'Assemble a bird house', 
    @sTime = '2011-01-05 12:00', @eTime = '2011-01-05 14:00' 

declare @usedItems table(itemID int) 
insert into @usedItems(itemID) 
select 1 union 
select 2 


declare @newTask table(taskID int) 
insert into tasks(description, sTimeUTC, eTimeUTC) 
output inserted.ID into @newTask 
values(@taskDes, @sTime, @eTime) 

insert into taskItems(taskID, itemID) 
select taskID, itemID 
from @newTask 
    cross join @usedItems 

今、私は新しいタスクの作成を単純化/合理化する方法。私の最初の考えは、ストアドプロシージャを使用することでしたが、テーブル変数は入力として使用することはできませんので、動作しません。私は挿入トリガーのビューでこれを行うことができると思いますが、わかりません...それは私の最高の(または唯一の)オプションですか?

+0

? SPは3つの変数だけをparamsとし、bodyは残りのコードにしますか? – RichardTheKiwi

+0

SP入力パラメータは '@testDes'、' @sTime'、@eTime'、および '@ usedItems'となります – chezy525

答えて

0

私はプロシージャにデータを渡すためにXMLを使用して幸運を持っていました。 OPENXML (Transact-SQL)を使用してXMLを解析できます。

-- You already had an example of @usedItems 
-- declared and populated in the question 
declare @usedItems table(itemID int) 
insert into @usedItems(itemID) 
select 1 union 
select 2 

-- Build some XML, either directly or from a query 
-- Here I demonstrate using a query 
declare @itemsXML nvarchar(max); 
select @itemsXML = 
    '<Items>' 
    + (select itemID from @usedItems as Item for xml auto) 
    + '</Items>' 

print @itemsXML 

-- Pass @itemsXML to the stored procedure as nvarchar(max) 

-- Inside the procedure, use OPENXML to turn the XML 
-- back into a rows you can work with easily 

DECLARE @idoc int 
EXEC sp_xml_preparedocument @idoc OUTPUT, @itemsXML 

SELECT * 
FROM OPENXML (@idoc, '/Items/Item',1) 
     WITH (itemID int) 

EXEC sp_xml_removedocument @idoc 

結果あなたがSPにしたいですかその一部

<Items><Item itemID="1"/><Item itemID="2"/></Items> 
itemID 
----------- 
1 
2 
+0

入力XMLの構造を保証する方法がないので、特に気に入らないのです。それは、これが現在利用可能な最良のオプションであるように見えます。 – chezy525

関連する問題