Форум программистов, компьютерный форум, киберфорум
Наши страницы
Delphi: Базы данных
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 5.00/4: Рейтинг темы: голосов - 4, средняя оценка - 5.00
kobakoba7
1 / 1 / 0
Регистрация: 21.05.2016
Сообщений: 280
1

Транзакции вместе циклом из Дельфи

06.02.2018, 10:28. Просмотров 670. Ответов 25
Метки нет (Все метки)

здравствуйте.
я столкнулся вот с такой проблемы, из delphi циклам передаются значение mysql в хранимую процедуру.задача такая
при ашипке должен произойти аткат. откат то делается но последний значении который пришел циклом из делфи в цикле из делфи передаются со стринггрида страки
и я хочу чтоб все страки откатились ане толка адин.
вот код:
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
CREATE DEFINER=`root`@`%` PROCEDURE `produqcial`( 
  IN `molare` VARCHAR(20), 
  IN `users` VARCHAR(20),
  IN `distributori` VARCHAR(20), 
  IN `shtrixkodi` BIGINT(15),  
  IN `dasaxeleba` VARCHAR(50),
  IN `raodenoba` VARCHAR(20),
  IN `tipi` VARCHAR(20),
  IN `fasi` VARCHAR(20),
  IN `jami` VARCHAR(20),
  IN `mogeba` VARCHAR(20)
)
BEGIN
DECLARE err INT DEFAULT 0;
proc: BEGIN
DECLARE N INT(5);
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET err=1;
START TRANSACTION;
IF (shtrixkodi <> '111') THEN
SET N = (SELECT AUTO_INCREMENT  FROM information_schema.tables WHERE TABLE_NAME='table1');
UPDATE   // здесь обыкновенны UPDATE
INSERT INTO  // здесь обыкновенны INSERT  
LEAVE proc;
END IF;
INSERT INTO   // здесь обыкновенны INSERT  как только shtrixkodi будет равно '111' этим узнаю что страки в стринггрид кончились и исполнение кода переходит суда
END;
IF (err=0) THEN
COMMIT; 
ELSE 
ROLLBACK; 
SELECT 'eror';
END IF;
END$$
и хачу что если ашыпка будет всё аткатилось а не толка паследное перед ашипкой.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.02.2018, 10:28
Ответы с готовыми решениями:

Импорт кода из Дельфи-файла без установленного Дельфи
Есть файлы проекта делфи, как без установленного делфи просмотреть код...

Скажите пожалуйста почему у дельфи 6,7 нет совместимости с Windows 7 и какая версия дельфи совместима с windows 7
Скажите пожалуйста почему у дельфи 6,7 нет совместимости с Windows 7. и какая...

Транзакции в delphi
Всем доброго времени! Помогите разобрать с транзакциями. Есть задание -...

Трехзвенка и транзакции
Всем привет, просветите кто знает (понимает суть процессов) В...

Откат транзакции?
Всем привет! Такая проблема. Есть текстовый файл с большим кол-вом...

25
qwertehok
2324 / 2225 / 606
Регистрация: 29.08.2013
Сообщений: 14,913
06.02.2018, 13:49 2
значит в цикле не только обновляй значения, но и куда то записывай старые
при ошибке эти старые значения возвращай обратно
0
kobakoba7
1 / 1 / 0
Регистрация: 21.05.2016
Сообщений: 280
06.02.2018, 14:37  [ТС] 3
qwertehok, я думал про такой подход, если так сделаю то никуда не надо записывать, вить встрингриде остаются страки,стираются когда код до конца дойдет в делфи конечно. я ищу подумал может временную таблицу использовать но как не знаю.
еще такой вариант все страки которые придут из цикла отдельные страки поставить, но как не знаю
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
DECLARE err INT DEFAULT 0;
  BEGIN
  DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET err=1;
  START TRANSACTION;
 UPDATE   // здесь обыкновенны UPDATE
 UPDATE   // здесь обыкновенны UPDATE
 UPDATE   // здесь обыкновенны UPDATE
 UPDATE   // здесь обыкновенны UPDATE
 UPDATE   // здесь обыкновенны UPDATE
 INSERT INTO ..............;
  INSERT INTO ..................;
  INSERT INTO ...................... ;
  INSERT INTO ..............;
  END;
 IF (err=0) 
  THEN COMMIT; 
  ELSE ROLLBACK; 
 END IF;
такой подход уж наверняка всё откатить, короче не знаю как сделать пака думаю,
надеюсь оптимальны вариант паткинете
0
qwertehok
2324 / 2225 / 606
Регистрация: 29.08.2013
Сообщений: 14,913
06.02.2018, 14:56 4
да, так тоже можно
взять StringList, записать в него кучу UPDATE и выполнить
(есть еще возможность в Firedac использовать массовые операции)

тогда можно откатить и всю транзакцию целиком, и даже выполнить эту операцию в отдельном потоке
0
kobakoba7
1 / 1 / 0
Регистрация: 21.05.2016
Сообщений: 280
06.02.2018, 15:09  [ТС] 5
qwertehok, может вариант паткинете со StringList.
Цитата Сообщение от qwertehok Посмотреть сообщение
(есть еще возможность в Firedac использовать массовые операции)
а этим компонентам не знаю как пользоваться
0
qwertehok
2324 / 2225 / 606
Регистрация: 29.08.2013
Сообщений: 14,913
06.02.2018, 15:13 6
открой справку и сам напишешь
0
kobakoba7
1 / 1 / 0
Регистрация: 21.05.2016
Сообщений: 280
06.02.2018, 15:24  [ТС] 7
а где справка ?
0
qwertehok
2324 / 2225 / 606
Регистрация: 29.08.2013
Сообщений: 14,913
06.02.2018, 15:35 8
тут конечно
0
kobakoba7
1 / 1 / 0
Регистрация: 21.05.2016
Сообщений: 280
06.02.2018, 15:59  [ТС] 9
не вряд ли мне это поможет я могу только на конкретных примерах разобраться.со стринглистам я болимение знаю как работать но на моем примере как ?
0
qwertehok
2324 / 2225 / 606
Регистрация: 29.08.2013
Сообщений: 14,913
06.02.2018, 16:11 10
Цитата Сообщение от kobakoba7 Посмотреть сообщение
болимение
до слез)

я тебе дал ссылку, там примеры есть.

ЗЫ официальный язык форума русский или английский
0
kobakoba7
1 / 1 / 0
Регистрация: 21.05.2016
Сообщений: 280
06.02.2018, 16:19  [ТС] 11
этого форума русский английский не знаю к сожалению

Добавлено через 1 минуту
а там на английском гугл переводит но не точна
0
kobakoba7
1 / 1 / 0
Регистрация: 21.05.2016
Сообщений: 280
07.02.2018, 22:39  [ТС] 12
помогите из стринггрида такой массив получить `shtrixkodi` in (1,2,3,4,5,6); для WHERE
я мучаюсь и не получается

Добавлено через 1 час 2 минуты
что то не работает я вручную создал и вызвал но ошибка неизвестны столбец
SQL
1
CALL masivi(`shtrixkodi` IN ('4563625895479','4569652874569','1548741236985','4569652145874'));
Добавлено через 27 минут
Цитата Сообщение от kobakoba7 Посмотреть сообщение
что то не работает я вручную создал и вызвал но ошибка неизвестны столбец
SQLВыделить код
1
CALL masivi(`shtrixkodi` IN ('4563625895479','4569652874569','1548741236985','4569652145874'));
заработала проста поменял `shtrixkodi` на 'shtrixkodi'
щас жду помощи
Цитата Сообщение от kobakoba7 Посмотреть сообщение
помогите из стринггрида такой массив получить `shtrixkodi` in (1,2,3,4,5,6); для WHERE
я мучаюсь и не получается
Добавлено через 10 минут
Цитата Сообщение от kobakoba7 Посмотреть сообщение
заработала проста поменял `shtrixkodi` на 'shtrixkodi'
извините ошибся не работает
0
krapotkin
3483 / 3076 / 1062
Регистрация: 14.04.2014
Сообщений: 14,872
Записей в блоге: 15
07.02.2018, 23:38 13
чтобы сделать все что нужно,
1. откажитесь от commit/rollback внутри процедуры в базе
2. читаем пример из документации
Delphi
1
2
3
4
5
6
7
8
9
10
11
FDConnection1.StartTransaction;
try
  // здесь делаем все что нужно. в цикле или без него
  // если все идет хорошо то ничего не делаем и вызовется коммит
  // если нет, то достаточно вызвать raise Exception.Create('Какая-то ошибка');
  // и все ваши изменения откатятся 
  FDConnection1.Commit;
except
  FDConnection1.Rollback;
  raise;
end;
вопрос 2.
как из нескольких строк (стринггрид содержит просто строки)
получить одну... (Придумываю из головы)
Delphi
1
2
3
4
5
6
7
8
s:='(';
for i:=1 to 4 do
begin
  if i<>1 then
    s:=s+',';
  s:=s+Grid.cells[2,i];
end;
s:=s+')';
0
kobakoba7
1 / 1 / 0
Регистрация: 21.05.2016
Сообщений: 280
08.02.2018, 00:13  [ТС] 14
krapotkin,
процедуру вот щас такую поставил и работает если адно значение передать а массив как ?
SQL
1
2
3
4
5
6
7
8
9
DELIMITER $$
CREATE PROCEDURE GetFruits(IN fruitArray VARCHAR(255))
BEGIN
  SET @SQL = CONCAT('UPDATE praduqt SET kol = kol - 5 WHERE Name IN (', fruitArray, ')');
  PREPARE stmt FROM @SQL;
  EXECUTE stmt;
  DEALLOCATE PREPARE stmt;
END$$
DELIMITER ;
Добавлено через 1 минуту
krapotkin,
если честно из стринггрида два массива хочу получить втарой где 5 стаит вместо него надо

Добавлено через 4 минуты
s эта массив да наверное

Добавлено через 4 минуты
документация на английском а гугл не точно переводить и мне трудновата там разобраться

Добавлено через 2 минуты
а по моему исходя из моего кода кавычки лишние, если не ошибаюсь канечна

Добавлено через 9 минут
Incompatible types: 'Array' and 'string'
Цитата Сообщение от krapotkin Посмотреть сообщение
s:='(';
0
krapotkin
3483 / 3076 / 1062
Регистрация: 14.04.2014
Сообщений: 14,872
Записей в блоге: 15
08.02.2018, 00:14 15
Delphi
1
var s:string;
....

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
FDConnection1.StartTransaction;
try
s:='UPDATE praduqt SET kol = kol - 5 WHERE Name IN (';
for i:=1 to 4 do
begin
  if i<>1 then
    s:=s+',';
  s:=s+Grid.cells[2,i];
end;
s:=s+')';
 
showmessage('Вот мой SQL'#13+s);
 
fdquery1.sql.text := s;
fdquery1.execSQL;
  FDConnection1.Commit;
except
  FDConnection1.Rollback;
  raise;
end;
0
kobakoba7
1 / 1 / 0
Регистрация: 21.05.2016
Сообщений: 280
08.02.2018, 00:23  [ТС] 16
вот такой у меня массив
var a: array[1..5] of string;

Добавлено через 8 минут
а второй массив из стринггрида как туда пихнут вместо 5
0
krapotkin
3483 / 3076 / 1062
Регистрация: 14.04.2014
Сообщений: 14,872
Записей в блоге: 15
08.02.2018, 00:26 17
что я должен понять из того, что у вас есть массив A ???
стринггрид уже всё? отменился?

пишите точнее и подробнее, если хотите, чтобы вам помогли.

если хотите чтобы к строке S добавлялись элементы массива A через запятую, просто замените в примере Grid.Cells[2,i] на A[i]
0
kobakoba7
1 / 1 / 0
Регистрация: 21.05.2016
Сообщений: 280
09.02.2018, 01:12  [ТС] 18
Цитата Сообщение от kobakoba7 Посмотреть сообщение
вот такой у меня массив
Цитата Сообщение от krapotkin Посмотреть сообщение
что я должен понять из того, что у вас есть массив A ???
var a: array[1..5] of string;
здесь я просто подумал s эта массив ну ладно это не важно
Цитата Сообщение от krapotkin Посмотреть сообщение
стринггрид уже всё? отменился?
а как стринггрид атменит вит умения дание там записаны я должен аттуда взять значение
проста хочу разобраться из стринггрида как второй массив значений взять
Цитата Сообщение от krapotkin Посмотреть сообщение
s:='UPDATE praduqt SET kol = kol - 5 WHERE Name IN
вот где 5 написана

Добавлено через 8 минут
krapotkin, огромнейшее спасибо
насчет второго массива я сам додумался ну надеюсь во всяком случае если что опять обращусь к вам

Добавлено через 1 минуту
Delphi
1
2
3
4
5
6
7
8
9
10
11
with StringGrid1 do
  begin
    a:='';
    for i:=1 to RowCount - 2 do
    begin
      if i<>1 then
        a:=a+',';
      a:=a+cells[8,i];
    end;
    a:=a;
  end;
Добавлено через 22 часа 43 минуты

Цитата Сообщение от krapotkin Посмотреть сообщение
FDConnection1.StartTransaction;
try
* // здесь делаем все что нужно. в цикле или без него
* // если все идет хорошо то ничего не делаем и вызовется коммит
* // если нет, то достаточно вызвать raise Exception.Create('Какая-то ошибка');
* // и все ваши изменения откатятся
* FDConnection1.Commit;
except
* FDConnection1.Rollback;
* raise;
end;
не работает откат

Добавлено через 2 минуты
в цикле

Добавлено через 5 минут
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var i: integer;
    s: string;
begin
  with StringGrid1 do
 begin
  FDConnect_gayidva;  // procedura conect
  FDConnection1.StartTransaction;
  try
   for i := 1 to RowCount - 2 do
   begin
     s:='UPDATE `praduqt` SET `kol` = `kol` - '''+Cells[4,i]+''', `suma` = `kol` * `srednoe`,`suma1` = '+
     ' `kol` * `cena` WHERE `shtrixkodi` = '''+Cells[8,i]+''' ';
   fdquery1.Active:=false;
    fdquery1.SQL.Clear;
   fdquery1.sql.text := s;
   fdquery1.execSQL;
   FDConnection1.Commit;
   end;
   except
   FDConnection1.Rollback;
   raise;
    end;
 end;
Добавлено через 1 час 29 минут
Цитата Сообщение от kobakoba7 Посмотреть сообщение
DELIMITER $$
CREATE PROCEDURE GetFruits(IN fruitArray VARCHAR(255))
BEGIN
* SET @SQL = CONCAT('UPDATE praduqt SET kol = kol - (здесь тоже массив вставить) WHERE Name IN (', fruitArray, ')');
* PREPARE stmt FROM @SQL;
* EXECUTE stmt;
* DEALLOCATE PREPARE stmt;
END$$
DELIMITER ;
если возможно конечно проста хочу чтоб в одну строку получилось запрос
0
qwertehok
2324 / 2225 / 606
Регистрация: 29.08.2013
Сообщений: 14,913
09.02.2018, 08:25 19
ну раз ты используешь Firedac, то может тебе поможет ArrayDML
http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Array_DML_(FireDAC)
пример там есть

или делай по другому
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
FDConnect_gayidva;  // procedura conect
  FDConnection1.StartTransaction;
  fdquery1.Active:=false;
  try
   for i := 1 to RowCount - 2 do
   begin
     s:=s+ 'UPDATE `praduqt` SET `kol` = `kol` - '''+Cells[4,i]+''', `suma` = `kol` * `srednoe`,`suma1` = '+
     ' `kol` * `cena` WHERE `shtrixkodi` = '''+Cells[8,i]+''' '+#13#10;
   end;
 
    fdquery1.sql.text := s;
    fdquery1.execSQL;
    FDConnection1.Commit;
  end;
  except
    FDConnection1.Rollback;
    raise;
   end;
в переменную S сохрани ВСЕ строки с UPDATE
а потом выполни как 1 запрос (возможно нужно будет добавить ; в конце каждого UPDATE)
0
krapotkin
3483 / 3076 / 1062
Регистрация: 14.04.2014
Сообщений: 14,872
Записей в блоге: 15
09.02.2018, 11:18 20
просто commit нужно не в цикле делать, а после него.
тогда он подтвердит все действия с начала транзакции, а если произойдет ошибка, то действия откатятся по Rollback
0
09.02.2018, 11:18
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.02.2018, 11:18

Транзакции - Триггер - Откат
Добрый вечер. Rad 10.1, MySql На клиенте пишу код: начало транзакции и...

TDBChart закрывание транзакции
Есть DBChart, у которого есть несколько Series`ов чьи DataSource связанны с БД....

Cin вместе с циклом
char a; while(true){ std::cin &gt;&gt; a; std::cout &lt;&lt; a &lt;&lt; std::endl;...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru