Как реализовать "цепочку" изменений?

Обсуждение возникших проблем, предложений и ошибок SDAC компонентов
Ответить
vso
Сообщения: 39
Зарегистрирован: Чт 24 янв 2013 11:08

Как реализовать "цепочку" изменений?

Сообщение vso » Чт 24 янв 2013 11:23

Все добрый день!

Есть MSQuery с запросом на выборку данных из нескольких таблиц. После редактирования или вставки новых данных необходимо сделать изменения или вставить новые данные в разные таблицы.
Как правильно организовать эту операцию?

Причем если мы вставляем значения то нам нужно получить идентификатор записи присвоенный при вставке данных в первую таблицу и отправить его в следующем запросе на вставку данных во вторую таблицу...

AndreyZ
Devart Team
Сообщения: 328
Зарегистрирован: Чт 08 сен 2011 13:18

Re: Как реализовать "цепочку" изменений?

Сообщение AndreyZ » Чт 24 янв 2013 14:11

Здравствуйте,

Вы можете выполнить данную операцию используя хранимые процедуры. Для более детального ответа, приведите пожалуйста конкретный пример операции (с примером запроса и скриптом для создания таблиц которые используются в запросе) которую Вы хотите выполнить.

vso
Сообщения: 39
Зарегистрирован: Чт 24 янв 2013 11:08

Re: Как реализовать "цепочку" изменений?

Сообщение vso » Чт 24 янв 2013 14:26

У меня лежит компонент на форме TMSQuery и у него в свойстве SelectSQL выполняется такой запрос

Код: Выделить всё

SELECT DISTINCT dbo.Cable.ID_CABLE, dbo.Cable.KKS, dbo.Cable.REF_TYPE, dbo.Cable.REF_BOX, dbo.Track.REF_DESTINATION
FROM dbo.Cable INNER JOIN
    dbo.Track ON dbo.Cable.ID_CABLE = dbo.Track.REF_CABLE
затем после выполнения команды MSQuery.Insert и заполнения данных нужно осуществить вставку в две таблицы.

Код: Выделить всё

INSERT INTO dbo.Cable
  (KKS, REF_TYPE, REF_BOX)
VALUES
  (:KKS, :REF_TYPE, :REF_BOX)
SET :ID_CABLE = SCOPE_IDENTITY()
и

Код: Выделить всё

INSERT INTO dbo.Track
  (REF_DESTINATION, REF_CABLE)
VALUES
  (:REF_DESTINATION, :ID_CABLE)
причем :ID_CABLE это возвращенное значение при вставке в первую таблицу

AndreyZ
Devart Team
Сообщения: 328
Зарегистрирован: Чт 08 сен 2011 13:18

Re: Как реализовать "цепочку" изменений?

Сообщение AndreyZ » Чт 24 янв 2013 15:21

Для такой операции необходимо выполнить два независимых запроса к серверу. При вставке новой записи (TMSQuery.Insert), на сервер отправляется один запрос. Поэтому эту операцию можно выполнить только хранимой процедурой. Для этого Вам необходимо создать на сервере хранимую процедуру (принимающая четыре параметра: KKS, REF_TYPE, REF_BOX, REF_DESTINATION) которая и будет выполнять два независимых запроса. Для использования хранимой процедуры, Вам необходимо установить свойство TMSQuery.SQLInsert . Например:

Код: Выделить всё

MSQuery.SQLInsert.Text := 'execute InsertCableTrack @KKS=:KKS, @REF_TYPE=:REF_TYPE, @REF_BOX=:REF_BOX, @REF_DESTINATION=:REF_DESTINATION';

vso
Сообщения: 39
Зарегистрирован: Чт 24 янв 2013 11:08

Re: Как реализовать "цепочку" изменений?

Сообщение vso » Чт 24 янв 2013 18:01

Спасибо!

Но каково тогда предназначения TMSUpdateSQL????

Просто я встречал ранее компонент с почти таким же названием, когда делал приложения для Firebird, так вот он использовался именно для того чтобы выстраивать цепочку действий.

Там можно было указать до/после какого действия(вставка, изменение, удаление) он работает и можно было делать длинную цепочку из этих компонентов, указав порядок выполнения. При этом возвращаемые значения автоматом подставлялись в следующее звено и т.д.

AndreyZ
Devart Team
Сообщения: 328
Зарегистрирован: Чт 08 сен 2011 13:18

Re: Как реализовать "цепочку" изменений?

Сообщение AndreyZ » Пт 25 янв 2013 15:28

Да, компонент TMSUpdateSQL служит для выполнения запросов и его можно использовать для нескольких датасетов. Но, TMSUpdateSQL может выполнить только один запрос, а не два независимых, как этого требует операция описанная выше.

vso
Сообщения: 39
Зарегистрирован: Чт 24 янв 2013 11:08

Re: Как реализовать "цепочку" изменений?

Сообщение vso » Вс 27 янв 2013 10:36

Андрей, спасибо!

А скажите, я воспользовался вашей рекомендацией и создал процедуру, в TMSQuery в свойство InsertSQL написал:

Код: Выделить всё

Execute spAdd @par1=:field1 @par2=:field2 @par3 OUTPUT
Третий параметр у меня объявлен как выходной, вопрос как правильно написать что бы @par3 воспринималась как выходная переменная, присваивалась полю в датасете и далее использовалась бы в свойстве RefreshSQL????

AndreyZ
Devart Team
Сообщения: 328
Зарегистрирован: Чт 08 сен 2011 13:18

Re: Как реализовать "цепочку" изменений?

Сообщение AndreyZ » Пн 28 янв 2013 13:59

1. Выходной параметр должен иметь имя такое же как и поле в таблице.
2. Необходимо использовать обработчик BeforeUpdateExecute чтобы установить корректный тип параметра. Например:

Код: Выделить всё

procedure TForm1.MSQuery1BeforeUpdateExecute(Sender: TCustomMSDataSet;
  StatementTypes: TStatementTypes; Params: TMSParams);
begin
  if stInsert in StatementTypes then
    Params.ParamByName('id_cable').ParamType := ptOutput;
end;
При выполнении данных условий, значение выходного параметра будет присваиваться полю в датасете.

vso
Сообщения: 39
Зарегистрирован: Чт 24 янв 2013 11:08

Re: Как реализовать "цепочку" изменений?

Сообщение vso » Пн 28 янв 2013 14:57

Андрей, спасибо!

Скажите, а к синтаксису процедуры на стороне сервера есть какие либо требования?

Т.к. если я делаю такой запрос на сервере

Код: Выделить всё

DECLARE @ID int

exec pAddCable '4FGS4111', 3, 383, 548, @ID OUT

PRINT RTRIM(CAST(@ID AS VARCHAR(20)))
я получаю выходное значение.

А вот выполняя такую инструкцию через MSQuery

Код: Выделить всё

Execute pAddCable @KKS=:KKS, @REF_TYPE=:REF_TYPE, @REF_BOX=:REF_BOX, @REF_DEST=:REF_DESTINATION, @ID_CABLE=:ID_CABLE
и написав присвоение типа, как Вы написали выше я в dbMonitor вижу, что у этого параметра тип и правду стоит OUT, In Value = NULL и OUT Value = NULL????

Так и не удается достичь желаемого результата :cry:

AndreyZ
Devart Team
Сообщения: 328
Зарегистрирован: Чт 08 сен 2011 13:18

Re: Как реализовать "цепочку" изменений?

Сообщение AndreyZ » Пн 28 янв 2013 16:18

Вам следует указать в Вашем запросе что параметр ID_CABLE является OUT параметром. Например:

Код: Выделить всё

Execute pAddCable @KKS=:KKS, @REF_TYPE=:REF_TYPE, @REF_BOX=:REF_BOX, @REF_DEST=:REF_DESTINATION, @ID_CABLE=:ID_CABLE OUT

Rajoe
Сообщения: 24
Зарегистрирован: Пн 24 сен 2012 15:16

Re: Как реализовать "цепочку" изменений?

Сообщение Rajoe » Чт 07 фев 2013 15:30

Хотя и немного поздновато уже, но добавлю ещё один вариант: для получения данных использовать не запрос к объединённым таблицам, а запрос к представлению, в котором эти таблицы уже объединены, а для изменения данных в таблицах использовать триггеры типа INSTEAD OF этого представления. По-моему, это простое и гибкое решение.

Ответить