Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / FoxPro, Visual FoxPro Новый топик    Ответить
 SQL запрос (INSERT) c инкрементацией ID  [new]
faustgreen
Member

Откуда:
Сообщений: 325
Таблица 1:
id name
1 Иван


Таблица 2:
id name
0 Петр
0 Дмитрий


Нужно добавить записи из таблицы 2 в таблицу 1 и при этом при добавлении каждой новой записи инкрементировать id. Может кто подскажет, как это сделать одним запросом? Пробовал сделать так:

INSERT INTO tab1(id, name);
SELECT (SELECT MAX(id)+1 FROM tab1), name FROM tab2


Получил:
id name
1 Иван
2 Петр
2 Дмитрий

а нужно:
id name
1 Иван
2 Петр
3 Дмитрий
11 янв 19, 11:38    [21782575]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос (INSERT) c инкрементацией ID  [new]
Dima T
Member

Откуда:
Сообщений: 13673
Для этого есть автоинкремент.
create cursor test( id i autoinc, name c(10))
insert into test (name) values ('Петя')
insert into test (name) values ('Вася')
brow
11 янв 19, 11:47    [21782590]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос (INSERT) c инкрементацией ID  [new]
faustgreen
Member

Откуда:
Сообщений: 325
Dima T, Это понятно, а если поле ID не с автоинкрементом? Есть ли способ?
11 янв 19, 11:52    [21782595]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос (INSERT) c инкрементацией ID  [new]
Sergej_S
Member

Откуда: Латвия
Сообщений: 274
Если скорость не принципиальна, то можно:

SELECT tab1
CALCULATE MAX(id) to nMaxId

SELECT tab2
GO TOP 
SCAN
  nMaxId = nMaxId+1
  INSERT INTO tab1 (id, name) VALUES (nMaxId, name)
ENDSCAN



Можно и покрасивее, но фокса под рукой нету, не могу проверить (возможно путаю), но типа такого:

INSERT INTO tab1 (id, name) ;
SELECT recno() +nMaxId, name FROM tab2
11 янв 19, 12:26    [21782654]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос (INSERT) c инкрементацией ID  [new]
faustgreen
Member

Откуда:
Сообщений: 325
Sergej_S, я в принципе так и делал (через scan).

По поводу :
INSERT INTO tab1 (id, name) ;
SELECT recno() +nMaxId, name FROM tab2

попробовал - не работает, результат тот же что и у меня (Fox походу это выражение вычисляет один раз и подставляет его во все строки при вставке)
11 янв 19, 12:36    [21782668]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос (INSERT) c инкрементацией ID  [new]
faustgreen
Member

Откуда:
Сообщений: 325
Упс, не сходу понял код, возможно ваш вариант и пройдет
INSERT INTO tab1 (id, name) ;
SELECT recno() +nMaxId, name FROM tab2
11 янв 19, 12:38    [21782673]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос (INSERT) c инкрементацией ID  [new]
Dima T
Member

Откуда:
Сообщений: 13673
Сделай через курсор
lnMaxId = ....
create cursor test( id i autoinc nextvalue lnMaxId, name c(10))

Сначала вставь name в курсор, они там прономеруются, затем с номерами вставляй в конечную таблицу.

Только учти что если несколько пользователей будут одновременно это делать, то будут задвония ID.
11 янв 19, 12:43    [21782685]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос (INSERT) c инкрементацией ID  [new]
faustgreen
Member

Откуда:
Сообщений: 325
Попутный вопрос про автоинкремент:
Допустим у нас есть таблица
Table
с автоинкрементным полем
id

Гарантирует ли следующий код, что функция
GetAutoIncrementValue
вернет именно то значение, которое было установлено для последней добавленной нами записи (даже если другой пользователь добавил новую запись в промежутке между выполнением команды 1 и 2):
№1 insert into table(name) values("Вася")
№2 getAutoIncremetnValue()
?
11 янв 19, 12:50    [21782697]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос (INSERT) c инкрементацией ID  [new]
faustgreen
Member

Откуда:
Сообщений: 325
У меня просто есть две таблицы:

TABLE1
id_tab1 field1
1 Вася


TABLE2
id_tab2 id_tab1 field2
1 1 Заказ1
2 1 Заказ2


Допустим поля id_tab1 и id_tab2 - автоинкрементные. Нужно сначала добавить запись в первую таблицу. А потом, например, еще 2 записи во вторую таблицу и при этом в качестве id_tab1 взять значение только что сгенерировнного id.

Такой код будет корректным ?:
insert into table1
lnId = getAutoIncrementValue() 
insert into table2 (...) values (..., lnId)
11 янв 19, 13:00    [21782712]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос (INSERT) c инкрементацией ID  [new]
Dima T
Member

Откуда:
Сообщений: 13673
Вернет id Васи. Смотри хэлп GETAUTOINCVALUE()
Возвращаемое функцией GETAUTOINCVALUE( ) последнее значение для автоинкрементного поля создается вне зависимости произошло ли реальное изменение данного поля в источнике данных. Возвращается значение =.NULL., если для заданной сессии данных еще не создано соответствующее значение автоинкрементного поля. Например, если еще не производилось никаких изменений источника данных (добавления записей), то возвращается значение =.NULL.


Но эта функция вообще не нужна, т.к.
insert into table(name) values("Вася")

переместит указатель на добавленную строку, поэтому достаточно использовать table.id
insert into table2 (...) values (..., table.id)
11 янв 19, 13:04    [21782719]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос (INSERT) c инкрементацией ID  [new]
Sergej_S
Member

Откуда: Латвия
Сообщений: 274
faustgreen
Гарантирует ли следующий код, что функция
GetAutoIncrementValue
вернет именно то значение, которое было установлено для последней добавленной нами записи (даже если другой пользователь добавил новую запись в промежутке между выполнением команды 1 и 2):
№1 insert into table(name) values("Вася")
№2 getAutoIncremetnValue()
?


Подозреваю, что вернет правильно, хотя я с автоинкрементом не работал. Почитай хелп фокса по getAutoIncremetnValue(), попробуй на практике из командного окна, открыв 2 фокса.
11 янв 19, 13:09    [21782735]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос (INSERT) c инкрементацией ID  [new]
faustgreen
Member

Откуда:
Сообщений: 325
В общем ушел тестировать, спасибо за советы!
11 янв 19, 13:17    [21782751]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос (INSERT) c инкрементацией ID  [new]
alboro73
Member

Откуда:
Сообщений: 15
Лучше поздно, чем никогда. Это кстати самое главное преимущество фокса. ....
Поле должно быть индексировано(лучше заранее).
INDEX ON id TAG id
Предварительно можно зафиксировать статус-кво по SET NEAR и SET ORDE
m.NEAR_=SET("NEAR")
m.ORDE_=SET("ORDE")
Берем max. значение для поля(например для 5-ти значного 99999).
Вкл.мягкий поиск
SET NEAR ON
Вкл. поиск по убыванию.
SET ORDE TO id DESC
SEEK 99999
Стали на запись с max-значением
m.IDMAX=table.id
Верните статус-кво
SET NEAR &m.NEAR_
SET ORDE &m.ORDE_

Добавляйте(вставляйте) запись с table.id=m.IDMAX+1
И не надо циклов со SCAN/WHILE. Кстати, из опыта цикл по WHILE выполняется быстрее
6 фев 19, 12:07    [21802565]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос (INSERT) c инкрементацией ID  [new]
Березовский
Member

Откуда:
Сообщений: 557
Велосипедистам привет.

Смотрите штатный пример в фоксе- Solution.pjx

База данных newsid- показан простой способ генерации id
в хранимой процедуре БД
8 фев 19, 13:25    [21804294]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос (INSERT) c инкрементацией ID  [new]
Dima T
Member

Откуда:
Сообщений: 13673
Березовский
Велосипедистам привет.

Смотрите штатный пример в фоксе- Solution.pjx

База данных newsid- показан простой способ генерации id
в хранимой процедуре БД

Привет, археолог. Это было актуально до появления полей с AUTOINC
8 фев 19, 13:53    [21804336]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос (INSERT) c инкрементацией ID  [new]
Березовский
Member

Откуда:
Сообщений: 557
Так тут конкретный вопрос
автор
Dima T, Это понятно, а если поле ID не с автоинкрементом? Есть ли способ?

про +1
8 фев 19, 13:57    [21804344]     Ответить | Цитировать Сообщить модератору
Все форумы / FoxPro, Visual FoxPro Ответить