Russian Qt Forum
Май 25, 2024, 22:15 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Запрос на обновление в sqlite  (Прочитано 11496 раз)
Karl-Philipp
Гость
« : Январь 22, 2009, 16:45 »

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

В базе данных есть 2 таблицы, созданные таким образом

Код:
CREATE TABLE rootTable(
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  idName VARCHAR(10) NOT NULL
);

CREATE TABLE dataTable(
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  rootTableId INTEGER(10) NOT NULL,
  rootTableIdName VARCHAR(10)
);

первая таблица заполнена значениями, во второй тоже есть записи, в которых не заполнено поле rootTableIdName.
Подскажите, пожалуйста, как сделать запрос на заполнение поля rootTableIdName в таблице dataTable, если данное поле должно заполняться на основе сравнения полей rootTableId из dataTable
и id из rootTable ()?
« Последнее редактирование: Январь 22, 2009, 17:09 от terlan » Записан
Rcus
Гость
« Ответ #1 : Январь 22, 2009, 17:10 »

ну наверно самым очевидным способом так:
Код
SQL
UPDATE dataTable SET rootTableIdName = (SELECT idName FROM rootTable WHERE rootTable.id = rootTableId);
Записан
Karl-Philipp
Гость
« Ответ #2 : Январь 22, 2009, 17:11 »

ну наверно самым очевидным способом так:
Код
SQL
UPDATE dataTable SET rootTableIdName = (SELECT idName FROM rootTable WHERE rootTable.id = rootTableId);
спасибо большое Улыбающийся
Записан
Karl-Philipp
Гость
« Ответ #3 : Январь 26, 2009, 11:32 »

Возникла необходимость обновить данные поля sequenceId в порядке возрастания натуральных чисел (1,2,3...,N).
Код
SQL
CREATE TABLE dataTable(
 id INTEGER PRIMARY KEY AUTOINCREMENT,
 flagId INTEGER,
 squenceId INTEGER,
);
Обновляться должны те данные в sequenceId, у которых в записи присутствует конкретный флаг (flagId)

Решил создать временную таблицу для записи id из dataTable, после чего обновляю dataTable.sequenceId из временно созданной таблицы:

Код
C++ (Qt)
QSqlDatabase db;
int colId;
...
QSqlQuery query(db);
if (query.exec(QString("CREATE TEMP TABLE tempSequence(id INTEGER PRIMARY KEY AUTOINCREMENT, dataTableId INTEGER NOT NULL)"))) {
  if (query.exec(QString("INSERT INTO tempSequence(dataTableId) SELECT id FROM dataTable WHERE flagId = %1)")
   .arg( QVariant( colId ).toString())   )) {  
     if (query.exec(QString("UPDATE dataTable SET sequenceId = (SELECT id FROM tempSequence WHERE dataTable.id = dataTableId")))
     {
      //dosmth
     }
  }
}


То есть, если данные таблицы dataTable были такими
Цитировать
1|1|
2|1|
3|2|
4|2|
5|2|
после выполнения предложенных выше запросов, данные в таблице dataTable при colId = 2 должны выглядеть так:
Цитировать
1|1|
2|1|
3|2|1
4|2|2
5|2|3
вроде должно работать, но может есть какой-то более оптимальный вариант?    

« Последнее редактирование: Январь 26, 2009, 11:35 от terlan » Записан
Tonal
Гость
« Ответ #4 : Январь 26, 2009, 11:51 »

Вообще-то никто не обещал, что SELECT внутри INSERT-а будет возвращать записи именно в порядке возрастания id.
Так что самое надёжное - цикл ручками. Улыбающийся
Записан
Karl-Philipp
Гость
« Ответ #5 : Январь 26, 2009, 12:01 »

а если упорядочить?
Код
SQL
INSERT INTO tempSequence(dataTableId) SELECT id FROM dataTable WHERE flagId = %1 ORDER BY id)

------------------
если приведенный вариант не подойдет, направьте, пожалуйста, как с помощью цикла выбирать нужные мне id?
« Последнее редактирование: Январь 26, 2009, 14:18 от terlan » Записан
Tonal
Гость
« Ответ #6 : Январь 27, 2009, 09:53 »

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

Ну а руками вроде просто - читать в цикле SELECT id FROM dataTable WHERE flagId = %1 и вызывать на каждый
UPDATE dataTable SET sequenceId = %1 WHERE dataTable.id = %2 - где первый параметр - счётчик, а второй id.
Записан
Karl-Philipp
Гость
« Ответ #7 : Январь 28, 2009, 09:58 »

Tonal, спасибо, наверное так и сделаю.

Однако возник еще один вопрос, связанный с обновлением  данных. В продолжение третьего поста этой темы:
(Возникла необходимость обновить данные поля sequence в порядке возрастания натуральных чисел (1,2,3...,N) для конкретных flagId.

Была задействована временная таблица для записи id из таблицы t c учетом конкретных flagId. После чего обновлялось поле sequence из поля id временной таблицы. Далее удалялись записи временной таблицы и выбирался новый flagId для заполнения временной таблицы:

Код
SQL
sqlite> CREATE TABLE t (id integer PRIMARY KEY, flagId integer, sequence integer);
sqlite> INSERT INTO t (flagId) VALUES (1);
sqlite> INSERT INTO t (flagId) VALUES (1);
sqlite> INSERT INTO t (flagId) VALUES (1);
sqlite> INSERT INTO t (flagId) VALUES (2);
sqlite> INSERT INTO t (flagId) VALUES (2);
sqlite> INSERT INTO t (flagId) VALUES (2);
sqlite> INSERT INTO t (flagId) VALUES (2);
sqlite> SELECT * FROM t;
1|1|
2|1|
3|1|
4|2|
5|2|
6|2|
7|2|
sqlite> CREATE temp TABLE tt(id integer PRIMARY KEY, t_id integer);
sqlite> INSERT INTO tt(t_id) SELECT id FROM t WHERE flagId = '1';
sqlite> SELECT * FROM tt;
1|1
2|2
3|3
sqlite> UPDATE t SET sequence = (SELECT id FROM tt WHERE t.id = t_id ORDER BY id);
sqlite> DELETE FROM tt;
sqlite> SELECT * FROM t;
1|1|1
2|1|2
3|1|3
4|2|
5|2|
6|2|
7|2|
sqlite> SELECT * FROM tt;
sqlite> INSERT INTO tt(t_id) SELECT id FROM t WHERE flagId = '2';
sqlite> SELECT * FROM tt;
1|4
2|5
3|6
4|7
sqlite> UPDATE t SET sequence = (SELECT id FROM tt WHERE t.id = t_id ORDER BY id);
sqlite> SELECT * FROM t;
1|1|
2|1|
3|1|
4|2|1
5|2|2
6|2|3
7|2|4
sqlite>

подскажите, пожалуйста, почему удалились значения t.sequence (1,2,3), которые были вставлены ранее?
Как надо правильно сделать?
Записан
Tonal
Гость
« Ответ #8 : Январь 28, 2009, 11:08 »

Возможно ты что-то не от с транзакциями.
Такое впечатление, что второй и третий SELECT * FROM t; проходят в разных транзакциях. Причём первая завершилась по ROLLBACK.

Да и поведение временной таблицы странное - если там AUTOINCREMENT (как в твоём 3ем посте) на первичном ключе, то вторая последовательность должна начинаться с id = 4.

П.С. Ты точную запись сессии привёл, или собрал из нескольких и подредактировал? Улыбающийся
Записан
Karl-Philipp
Гость
« Ответ #9 : Январь 28, 2009, 11:14 »

последний вариант - сделал заново. Привёл точную запись сессии из консоли Улыбающийся
« Последнее редактирование: Январь 28, 2009, 11:27 от terlan » Записан
Rcus
Гость
« Ответ #10 : Январь 28, 2009, 11:41 »

UPDATE без условия выборки применяется ко всем записям в таблице, пустая выборка соответствует NULL значению.
Записан
Karl-Philipp
Гость
« Ответ #11 : Январь 28, 2009, 11:53 »

Rcus, спасибо большое.
заменил
Код
SQL
UPDATE t SET sequence = (SELECT id FROM tt WHERE t.id = t_id ORDER BY id);
на
Код
SQL
UPDATE t SET sequence = (SELECT id FROM tt WHERE t.id = t_id ORDER BY id) WHERE sequence IS NULL;
и заработало Улыбающийся
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.087 секунд. Запросов: 17.