2011-01-20 2 views
0

Я пытаюсь найти хорошую работу, чтобы не использовать табличную переменную в качестве входа в хранимую процедуру. Я хочу вставить одну запись в базовую таблицу и несколько записей в сводную таблицу. Мой первоначальный процесс мысли привел меня к желанию хранимой процедуры с отдельными входами для базовой таблицы, и один входа списка для записей таблицы поворота, то есть:SQL Server: Сохранение переменной таблицы входных данных Proc

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 (я полагаю, в первую очередь, из-за проблем с переменной областью). Итак, есть ли хорошие обходные пути?

Оригинал Вопрос
У меня есть три таблицы:

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 

Теперь, я wa nt способ упрощения/оптимизации создания новых задач. Моя первая мысль заключалась в использовании хранимой процедуры, но переменные таблицы не могут использоваться в качестве входных данных, поэтому это не сработает. Я думаю, что могу сделать это с помощью триггера вставки, но я не уверен ... Это мой лучший (или единственный) вариант?

+0

Какую часть этого вы хотите в СП? Будет ли SP брать только 3 переменные вверх, как параметры, а тело - остальную часть вашего кода? – RichardTheKiwi

+0

Параметрами ввода SP будут '@ taskDes',' @ 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 

Результаты

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

Мне это не особенно нравится, потому что нет возможности гарантировать структуру входного xml. Тем не менее, похоже, что это лучший вариант, доступный в настоящее время. – chezy525

Смежные вопросы