2011-12-15 3 views
0

У меня есть много-много отношений между табличным продуктом и порядком таблицы, таблица ссылок - ProductInOrder. Я хочу сделать хранимую процедуру со списком идентификаторов продуктов в качестве входных данных и что он будет делать, это создать новый порядок и добавить новую запись в таблицу ссылок для каждого продукта.Несколько вставок в хранимых процедурах

Теперь я достиг этого, используя транзакцию, инициированную клиентом, а затем вызвал sp для создания нового порядка, а затем цикл в клиенте для вызова sp для создания каждой записи в таблице ссылок. Но должен быть способ сделать это в sql.

Любые идеи?

Лучшие

+3

Вы спрашиваете, как писать запрос, но трудно ответить, если мы не знаем, какие RDBMS вы используете (Oracle, MySQL, SQL Server, PostGreSQL, SQLite ...) и какую версию этой СУБД. Их реализация SQL отличается, и есть функции, которые мы могли бы использовать для повышения эффективности запросов, например. Кроме того, синтаксис SQL может отличаться. – Benoit

+0

@Benoit Также здесь очень важен клиент, так как не все клиенты могут воспользоваться всеми функциями данной RDBMS. –

+0

Я использую C# и MSSQL, но я хочу это как пример, а не приложение для реальной жизни. – BCartolo

ответ

1

То, что вы хотите что-то вроде этого (для MSSQL, по крайней мере):

declare @Sql varchar(max) = ' 
insert into ProductInOrder (OrderID, ProductID) 
select 
    ' + @OrderID + ', 
    ProductID 
from 
    Product 
where 
    ProductID in (' + @Products + ')' 

sp_executesql(@Sql) 

Pass @Products как разделенные запятыми строки целых чисел, e.g.- '1,2,3,15,100'.

Чтобы загрузить временную таблицу в C#, вы могли бы сделать это (используя SqlCommand имени comm):

comm.CommandText = "create table #ProductList (ProductID int)"; 
comm.ExecuteNonQuery(); 
comm.CommandText = "insert into #ProductList (ProductID) values (@ProductID)"; 
foreach(int product in products) 
{ 
    comm.Parameters.Clear(); 
    comm.Parameters.AddWithValue("@ProductID", product); 
    comm.ExecuteNonQuery(); 
} 
comm.Parameters.Clear(); 
comm.Parameters.AddWithValue("@OrderID", orderId); 
comm.CommandText = "insert into ProductInOrder (OrderID, ProductID) " + 
    "select @OrderID, p.ProductID from Product p inner join #ProductList pl on " + 
     "p.ProductID = pl.ProductID"; 
comm.ExecuteNonQuery(); 
comm.CommandText = "drop table #ProductList"; 
comm.ExecuteNonQuery(); 
+0

Это актуально довольно хорошо. Нет никакого способа сделать это без динамического SQL? – BCartolo

+0

К сожалению, нет. Вы можете загрузить временную таблицу, если хотите, и передать ее, но вы не можете передать массив значений напрямую. Ниже перечислены только те типы данных, которые вы можете передать: http://msdn.microsoft.com/en-us/library/yy6y35y8.aspx – Eric

+0

Временная таблица вещей многообещающая, я посмотрю, смогу ли я придумать пример. – BCartolo

0

Это еще один вариант, который выполняет великолепно и сокращает количество спуско-к сервера из вашего приложения.

http://msdn.microsoft.com/en-us/library/bb510489.aspx

выполняет очень хорошо в сценарии я использовал его. Действительно отличный вариант. В Интернете есть примеры, которые можно просмотреть, поскольку я не могу найти свое доказательство концепции I, которое я реализовал для него. Это требует создания типа данных таблицы в целевой базе данных.

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