Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Горит диплом!Не могу написать процедуру!  [new]
Janete
Guest
Пишу диплом с использованием базы на MS SQL-сервер.
Шарю не очень, в книгах ни фига нету.
Помогите написать процедуру!

Смысл такой: нужно занести данные в две таблицы, данные передаю как параметры.

Но в одной таблице поле Id_document - идентификатор (увеличивается сам), а в

другую нужно сразу занести данные и этот идентификатор. Сейчас написал вот что:

CREATE PROCEDURE dbo.p_create_sopr_pasport
(@id_variant int,
@kol_vo int,
@number_sopr_pasport int,
@id_unit_item int,
@id_cite int = 2,
@type char(1)='C',
@state int = 0)
AS BEGIN
insert into t_Receipts
(Cite_of_customer,Type_of_receipt,Number_of_document,Cite_of_recipient,State)
values (@id_cite,@type,@number_sopr_pasport,@id_cite,@state)
insert into t_Receipt_items
(Id_document,Id_item_v,Id_unit,Item_count)
values (&&&,@id_variant,@id_unit_item,@kol_vo)
END

Вобщем вместо &&& надо написать какой-то select, который будет выбирать

Id_document из таблицы t_Receipts и передавать его в Id_document в таблицу

t_Receipt_items.

ПОМОГИТЕ!!!!!!!!!!!!!!
1 май 04, 15:51    [660919]     Ответить | Цитировать Сообщить модератору
 Re: Горит диплом!Не могу написать процедуру!  [new]
rst
Member

Откуда: Йобурк
Сообщений: 1005
SCOPE_IDENTITY()
1 май 04, 15:56    [660923]     Ответить | Цитировать Сообщить модератору
 Re: Горит диплом!Не могу написать процедуру!  [new]
Janete
Guest
Если можно, поподробнее...ничего не понимаю... :(
1 май 04, 16:41    [660947]     Ответить | Цитировать Сообщить модератору
 Re: Горит диплом!Не могу написать процедуру!  [new]
rst
Member

Откуда: Йобурк
Сообщений: 1005
Но в одной таблице поле Id_document - идентификатор (увеличивается сам), а в другую нужно сразу занести данные и этот идентификатор


BOL

SCOPE_IDENTITY
Returns the last IDENTITY value inserted into an IDENTITY column in the same scope
1 май 04, 17:19    [660967]     Ответить | Цитировать Сообщить модератору
 Re: Горит диплом!Не могу написать процедуру!  [new]
Janete
Guest
Чмок!Чмок!Чмок!
Спасибо!!!!!!!!!!!!
Получилось!!!!!!!


А это не будет нагло, если я задам еще один вопрос?

Есть функция, которая вычисляет остаток одного материала, как параметр ей передается Id материала.
А нужно вывести в приложение все материалы выбранного технологического маршрута, причем показать их остатки, необходимое количество (как произведение кол-ва для одного изделие на кол-во изделий) и дифицит...
Как бы это все объединить ???
1 май 04, 17:39    [660975]     Ответить | Цитировать Сообщить модератору
 Re: Горит диплом!Не могу написать процедуру!  [new]
rst
Member

Откуда: Йобурк
Сообщений: 1005
Сейчас написал вот что
Чмок!Чмок!Чмок!

э, э! - погоди - не надо чмокав тогда :)


Как бы это все объединить ???

Не очень понятен вопрос..
Проблема в составлении запроса?
приведите код таблиц и что надо получить..
(и лучше в отдельном топике)
если вопрос как использовать функцию в запросе - то так
select id from table ->
select id,dbo.Ostatok(id) from table
1 май 04, 18:06    [660984]     Ответить | Цитировать Сообщить модератору
 Re: Горит диплом!Не могу написать процедуру!  [new]
Janete
Guest
Шалун, как это не надо чмоков!?
Да, ладно, ну разве может быть Janete парнем?
Я - девушка, в таком случае чмоки принимаешь?!!

Ну так вот:
Есть таблица t_Receipts, хранящая документы.
Поля нужные для дела: id_var (вариант технологического маршрута изделия), id_count (количество изделий).

Есть таблица t_Items, хранящая данные об изделии, таблица t_Item_operations данные об операциях для производства изделия (но это не важно), и таблица t_Item_operation_items - данные о составе материалов по одной операции, где в сотаве ключевых полей тоже есть id_var.

Нужно вынуть из таблицы t_Item_operation_items поля Id_material, Count_of_material (т.е.на одно изделие) where t_Item_operation_items.id_var=t_Receipts.id_var.

А отобразить надо все в таком виде:

Col1: Id_material
Col2: t_Item_operation_items.Count_of_material*t_Receipts.id_count
Col3: fn_item_reminder(Id_material)
Col4: Col2-Col3

А вот сама функция вычисления остатка для одного материала, может ее как-то поправить чтобы для кучи вычисляла?

CREATE FUNCTION fn_Item_remainder (@id_item int)
RETURNS float
AS
BEGIN
DECLARE @remainder float
SELECT @remainder =
SUM(ri.Item_count *
dbo.fn_Factor_of_converting(i.Id, ri.Id_unit, i.Base_unit) *
CASE
WHEN (r.Cite_of_recipient = dbo.fn_Current_firm()) and
(r.Subcite_of_recipient = dbo.fn_Current_warehousing()) THEN 1
WHEN (r.Cite_of_customer = dbo.fn_Current_firm()) and
(r.Subcite_of_customer = dbo.fn_Current_warehousing()) THEN -1
ELSE 0
END)
FROM (SELECT dbo.t_Items.* FROM dbo.t_Items WHERE dbo.t_Items.Id = @id_item) i INNER JOIN
dbo.t_Item_variants iv ON iv.Id_item = i.Id LEFT OUTER JOIN
dbo.t_Receipt_items ri INNER JOIN
(SELECT dbo.t_Receipts.* FROM dbo.t_Receipts
WHERE (dbo.t_Receipts.Type_of_receipt = 'Н')AND
(dbo.t_Receipts.State = 2)) r ON r.Id_document = ri.Id_document
ON ri.Id_item_v = iv.Id_item_v
GROUP BY i.Id
RETURN @remainder
END
1 май 04, 18:40    [660991]     Ответить | Цитировать Сообщить модератору
 Re: Горит диплом!Не могу написать процедуру!  [new]
rst
Member

Откуда: Йобурк
Сообщений: 1005
ну тогда чмоки принимаются :)

я так понял для одного маршрута надо..
Вроде так :

/* @id_var int  - "выбранного технологического маршрута" */

declare @coun float
select @coun=id_count from t_Receipts where id_var=@id_var


select op_items.Id_material,op_items.Count_of_material*@coun,ostatok.ost from t_Item_operation_items op_items
join
(
/*reminder*/
select /*+*/ i.id, ost=SUM(ri.Item_count *
dbo.fn_Factor_of_converting(i.Id, ri.Id_unit, i.Base_unit) *
CASE
WHEN (r.Cite_of_recipient = dbo.fn_Current_firm()) and
(r.Subcite_of_recipient = dbo.fn_Current_warehousing()) THEN 1
WHEN (r.Cite_of_customer = dbo.fn_Current_firm()) and
(r.Subcite_of_customer = dbo.fn_Current_warehousing()) THEN -1
ELSE 0
END)
FROM
/*change*/
dbo.t_Items i
INNER JOIN
(select Id_material from t_Item_operation_items where id_var=@id_var group by Id_material ) op_items on (op_items.id_material=i.id)
/*end*/
INNER JOIN
dbo.t_Item_variants iv ON iv.Id_item = i.Id LEFT OUTER JOIN
dbo.t_Receipt_items ri INNER JOIN
(SELECT dbo.t_Receipts.* FROM dbo.t_Receipts
WHERE (dbo.t_Receipts.Type_of_receipt = 'Н')AND
(dbo.t_Receipts.State = 2)) r ON r.Id_document = ri.Id_document
ON ri.Id_item_v = iv.Id_item_v
GROUP BY i.Id
/*end reminder*/
)as ostatok on (ostatok.id=op_items.id_material)
where op_items.id_var=@id_var

ну и последнюю колонку не проблема добавить..

зы. проверить негде так что as is ..
1 май 04, 19:27    [661004]     Ответить | Цитировать Сообщить модератору
 Re: Горит диплом!Не могу написать процедуру!  [new]
Janete
Guest
Большое спасибо!
Я попытаюсь разобраться и вставить это.
Что получится, обязательно напишу.
1 май 04, 22:08    [661037]     Ответить | Цитировать Сообщить модератору
 Re: Горит диплом!Не могу написать процедуру!  [new]
Janete
Guest
Гип-гип-ура!!! Ты - гений!!!
Она работает, все считает!!!
Огромеднейшее спасибо!!!...И 1000 чмоков! :) :) :)
1 май 04, 23:52    [661072]     Ответить | Цитировать Сообщить модератору
 Re: Горит диплом!Не могу написать процедуру!  [new]
Janete
Guest
Это опять я. Наверное, я злоупотребляю,но
у меня еще одна проблема.
Помоги пожалуйста!

Надо сформировать накладные по существующим документам, т.е.записать в таблицы несколько строк в цикле.

Вобщем: как параметр передаем @id_var и @count(количество производимых изделий)

Нужно select number_of_oper,id_cites
from t_item_operations
where id_var=@id_var
и для каждой строки полученной выборки вставить строку в таблицу t_Receipts (вставить выбранные поля, ну и там еще всякие стандартные вещи).

Где-то там внутри запроса еще надо написать
select id_material,count_of_material
from t_item_operation_items
where id_var=@id_var and
t_item_operation_items.number_of_oper=t_item_operations.number_of_oper
и опять же для каждой строки полученной выборки вставить строку в таблицу
t_Receipt_items (вставить id_material и count_of_material*@count, ну и там еще
всякие стандартные вещи).

Т.е.получается вложенный цикл.

Я могла бы написать сама простенькие процедуры для записи, а циклы организовать средствами приложения, но не хочется через ж...
2 май 04, 16:46    [661266]     Ответить | Цитировать Сообщить модератору
 Re: Горит диплом!Не могу написать процедуру!  [new]
rst
Member

Откуда: Йобурк
Сообщений: 1005
Вопрос то в чем все таки конкретно ??

циклы организовать средствами приложения

mssql поддерживает циклы и курсоры так что все это можно в хп делать..
см declare cursor..


Нужно select number_of_oper,id_cites
from t_item_operations
where id_var=@id_var
и для каждой строки полученной выборки вставить строку в таблицу t_Receipts (вставить выбранные поля, ну и там еще всякие стандартные вещи).


ну а почему цикл то нужен?
одним запросом то нельзя?
insert t_Receipts select поля,dbo.funct(чеготоеще),(select top 1 * from table where id_var=@id_var ).. from t_item_operations
where id_var=@id_var
2 май 04, 21:50    [661397]     Ответить | Цитировать Сообщить модератору
 Re: Горит диплом!Не могу написать процедуру!  [new]
Janete
Guest
Для t_Receipts:
insert into t_Receipts (....)
values (...,
select number_of_oper,id_cites
from t_item_operations
where id_var=@id_var)

А для t_Receipt_items для каждой вставленной строки в t_Receipts нужно вставить строки, которые
select id_material,count_of_material
from t_item_operation_items
where id_var=@id_var and t_item_operation_items.number_of_oper=t_item_operations.number_of_oper

Куда тогда это включить?

Здесь опять же в t_Receipts - идентификатор, который нужно записать в t_Receipt_items. Т.е. вставляем одну строку в t_Receipts и сразу несколько подчиненных ей в t_Receipt_items.
3 май 04, 11:49    [661527]     Ответить | Цитировать Сообщить модератору
 Re: Горит диплом!Не могу написать процедуру!  [new]
Mishau
Member

Откуда: Россия
Сообщений: 355
CREATE PROCEDURE dbo.p_create_sopr_pasport
(@id_variant int,
@kol_vo int,
@number_sopr_pasport int,
@id_unit_item int,
@id_cite int = 2,
@type char(1)='C',
@state int = 0)
AS
BEGIN
/*add*/
declare @Id_document int
begin transaction
/*add */
insert into t_Receipts
(Cite_of_customer,Type_of_receipt,Number_of_document,Cite_of_recipient,State)
values (@id_cite,@type,@number_sopr_pasport,@id_cite,@state)

/*add*/
if @@error <> 0 goto error
select @Id_document = max(Id_document) from t_Receipts
/*add*/

insert into t_Receipt_items
(Id_document,Id_item_v,Id_unit,Item_count)
values (/*add*/@Id_document/*add*/,@id_variant,@id_unit_item,@kol_vo)

/*add*/
if @@error <> 0 goto error
commit work
return
error:
rollback work
/*add*/

END
3 май 04, 12:06    [661540]     Ответить | Цитировать Сообщить модератору
 Re: Горит диплом!Не могу написать процедуру!  [new]
Glory
Member

Откуда:
Сообщений: 104764
Так - select @Id_document = max(Id_document) from t_Receipts - НЕ НАДО делать

Нужно написать триггер на INSERT для таблицы t_Receipts. В котором оперировать добавленными в t_Receipts записями через виртуальную таблицу inserted
3 май 04, 12:12    [661546]     Ответить | Цитировать Сообщить модератору
 Re: Горит диплом!Не могу написать процедуру!  [new]
Janete
Guest
@Id_document = max(Id_document) - так точно не прокатит.

Смысл в чем: имеем номер варианта технологического маршрута (@id_var). Каждый вариант технологического маршрута состоит из нескольких операций (т.е. выбираем select number_of_oper,id_cites
from t_item_operations
where id_var=@id_var ),
а для каждой операции определен набор материалов
(т.е. select id_material,count_of_material
from t_item_operation_items
where id_var=@id_var and t_item_operation_items.number_of_oper=t_item_operations.number_of_oper )

Нужно записать в таблицу t_Receipts данные об операции, а в t_Receipt_items состав операции, т.е. набор материалов.
Вобщем:
для t_Receipts выбираем и записываем первую строку(операцию), и сразу для нее выбираем и записываем состав материалов в t_Receipt_items. Затем вторую в t_Receipts и сразу кучку для нее в t_Receipt_items, и т.д.
3 май 04, 12:52    [661568]     Ответить | Цитировать Сообщить модератору
 Re: Горит диплом!Не могу написать процедуру!  [new]
rst
Member

Откуда: Йобурк
Сообщений: 1005
2Janete
Триггер на INSERT для таблицы t_Receipts
Подходит все таки или нет??
3 май 04, 13:44    [661593]     Ответить | Цитировать Сообщить модератору
 Re: Горит диплом!Не могу написать процедуру!  [new]
Janete
Guest
Я думаю нет.
В таблицу t_Receipts заносятся документы разных типов:планы продаж и производства, сопроводит.паспорта, накладные и т.д. И для разных документов по разному надо формировать таблицу t_Receipt_items (где-то одной записи в t_Receipts соответствует одна запись в t_Receipt_items, где-то много. Причем данные тоже берутся из разных таблиц - это не всегда операции и набор материалов)
3 май 04, 14:01    [661603]     Ответить | Цитировать Сообщить модератору
 Re: Горит диплом!Не могу написать процедуру!  [new]
rst
Member

Откуда: Йобурк
Сообщений: 1005
Поскольку диплом все равно никто читать не будет,опоры моста делаем деревянными :

1)По простому можно действительно сделать в цикле..
2)Есть такой вариант:
В одной транзакции - блокируем таблицу(чтоб никто не мог писать) , запоминаем @first=IDENT_CURRENT('tReceipts') затем одним запросом вставляем все записи туда которые надо..
после этого знаем все id которые вставили (они идут по порядку от @first+1 до scope_identity()) - по ним тоже скопом добавляем в items уже..
3 май 04, 14:38    [661628]     Ответить | Цитировать Сообщить модератору
 Re: Горит диплом!Не могу написать процедуру!  [new]
Janete
Guest
Мне уже все равно какие у моста будут опоры: сдавать скоро. И вообще нормальный выход. Если бы ты знал как я уже хотела это реализовать, то вставил бы еще не такую рожицу:)
Спасибо за помощь.
Что получится - напишу.
3 май 04, 15:06    [661640]     Ответить | Цитировать Сообщить модератору
 Re: Горит диплом!Не могу написать процедуру!  [new]
Glory
Member

Откуда:
Сообщений: 104764
Все равно ИМХО лучше будет в триггере добавить из таблицы inserted значения столбца с identity во временную таблицу(конечно предварительно проверив ее существование). А вот о создании и о дальнейшем использовании этой временной таблицы должно уже побеспокоиться тот кто инициироует срабатывание триггера.
3 май 04, 15:12    [661644]     Ответить | Цитировать Сообщить модератору
 Re: Горит диплом!Не могу написать процедуру!  [new]
Janete
Guest
Про виртуальные таблицы ничего не знаю???
3 май 04, 19:04    [661790]     Ответить | Цитировать Сообщить модератору
 Re: Горит диплом!Не могу написать процедуру!  [new]
Glory
Member

Откуда:
Сообщений: 104764
Про виртуальные таблицы ничего не знаю
Плохо
http://msdn.microsoft.com/library/en-us/createdb/cm_8_des_08_0lo3.asp
http://msdn.microsoft.com/library/en-us/createdb/cm_8_des_08_3ypf.asp
3 май 04, 20:15    [661823]     Ответить | Цитировать Сообщить модератору
 Re: Горит диплом!Не могу написать процедуру!  [new]
Janete
Guest
Я вроде написала эту процедуру, но она ругается. Синтаксисе SQL для меня темный лес, поэтому я не понимаю, что ей не нравится.

Вобщем вот процедура:

Create procedure dbo.p_create_nakladn
(@id_var int,
@num_doc varchar,
@count float)
As begin
declare @first int
declare @cite int
declare @type char(1)
declare @subcite int
declare @sch int
declare @id_cit int
set @first = IDENT_CURRENT('t_Receipts')
set @cite=2
set @type='Н'
set @subcite = 16
set @sch=@first
insert into t_Receipts
(Cite_of_customer,Type_of_receipt,Number_of_document,Cite_of_recipient,
Subcite_of_customer,Subcite_of_recipient)
values (@cite,@type,@num_doc,@cite,@subcite,(select Id_cites
from t_Item_operations where Id_item_v=@id_var))

while @sch<>SCOPE_IDENTITY()+1
begin
select @id_cit=id_cites from t_Receipts where Id_document=@sch
insert into t_Receipt_items
(Id_document,Id_item_v,Id_unit,Item_count,Party_number)
values (@sch,(select
var_mat,base_unit,count_of_material*@count,id_cites
from v_nakladn where id_item_v=@id_var and id_cites=@id_cit))

@sch=@sch+1
end
END

На красные строки ругается так:
Server: Msg 1046, Level 15, State 1, Procedure p_create_nakladn, Line 16
Subqueries are not allowed in this context. Only scalar expressions are allowed.


Типы полей и вставляемых значений совпадают. Подзапросы возвращают несколько строк. Так нельзя подзапросы вставлять? Или надо, чтобы возвращал только одно значение?Как же тогда сразу кучку вставить?
4 май 04, 17:44    [662309]     Ответить | Цитировать Сообщить модератору
 Re: Горит диплом!Не могу написать процедуру!  [new]
rst
Member

Откуда: Йобурк
Сообщений: 1005
уже ведь был тут выше приведен пример для insertа без values.

insert into t_Receipt_items 

(Id_document,Id_item_v,Id_unit,Item_count,Party_number)
select @sch, var_mat,base_unit,count_of_material*@count,id_cites
from v_nakladn where id_item_v=@id_var and id_cites=@id_cit
4 май 04, 17:52    [662314]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить