|
Тема
|
Insert в 2 таблици с една заявка
|
|
Автор | zakysal (Нерегистриран) |
Публикувано | 20.03.07 13:18 |
|
Здравейте!
Имам следните 2 таблици:
А с колони id и name Където ид е auto increment.
B с колони id, param, value където id е варзана за id на таблицата A.
Въпроса ми е дали може с един insert да вкарам записите в двете таблици. По-точно как да избачкам id-то дето е генерирано от insert-a в първата таблица за да мога да го ползвам при insert във втората таблица?
Проблема е че имам много потребители дето ползват базата и ако го правя с 2 insert-a и после SELECT MAX(ID) може да ми върне id дето е генерирано от друга заявка. С транзакция дали ще се реши проблема? Имам в предвид ако имам един insert, после селект и после няколко insert-а, всичко това в рамките на една транзакция. SELECT-а в тоя случай ще види ли id-тата генерирани от други потребителски заявки?
Поздрави.
| |
|
Най-вече не е ясно каква ти е базата. MS SQL например поддържа функция SCOPE_IDENTITY която ти връща последното автогенерирано ID в рамките на текущия scope(разбирай stored procedure), което ти решава проблема с Max(ID).
Предполагам, че и твоята база поддържа нещо подобно(освен ако не е Clipper).
| |
Тема
|
Re: Insert в 2 таблици с една заявка
[re: BlandingsCastle]
|
|
Автор | zakysal (Нерегистриран) |
Публикувано | 20.03.07 14:30 |
|
Значи едни клиенти ползват MySQL, други Oracle, трети M$ SQL server, ... Затова гледам да е нещо стандартно. Иначе с jdbc 3.0 драйвери си има getGeneratedKeys, ама не всеки драйвер го поддържа. Затова рекох ако има нещо стандартно дето да върви на повечето RDBMS ще е добре.
Все пак мерси за отделеното време.
Поздрави
| |
Тема
|
Re: Insert в 2 таблици с една заявка
[re: zakysal]
|
|
Автор |
wqw (АзСъмЖив) |
Публикувано | 20.03.07 16:14 |
|
Не няма, щото подобни синтетични "генерации" не са стандартни -- къде е IDENTITY property, къде Autonumber колона, къде bind на sequence обект.
Единствено на ниво DAL може да търсиш някаква абстракция -- ODBC, JDBC, ADO, etc.
cheers,
</wqw>
| |
Тема
|
Re: Insert в 2 таблици с една заявка
[re: zakysal]
|
|
Автор |
salle (един такъв) |
Публикувано | 21.03.07 01:12 |
|
Стандартно решение няма както wqw ти каза.
За всеки сървър си има съответното решение, но специфично и неработещо при другите.
В MySQL решението е да използваш LAST_INSERT_ID():
INSERT INT t1 .....;
INSERT INTO t2 (t1_id, .... )VALUES(LAST_INSERT_ID() ....
LAST_INSERT_ID() ти гарантира стойността на auto increment вмъкната от текущата сесия дори и да има други паралелно работещи сесии за разлика от MAX(id).
Едно по-генерално решение поне на теория е да заключваш първата таблица за писане, но това също не всеки сървър ще ти го позволи.
Също на теория при максималното ниво на изолация на транзакции (което също варира) би трябвало да можеш да изпълниш:
START TRANSACTION;
SELECT MAX(ID) ...
INSERT ...
и да разчиташ, че нивото на изолация ти гарантира нова стойност MAX+1
Само, че тове е в "сивата област" където обитават фантоми и други подобни.
Изобщо ако ти трябва преносимо решение което да работи независимо от сървъра по-добре се ориентирай към решение от страната на клиентското приложение.
Или още по-добре използвай уникални идентификатори в стил UUID() и подобни
и да е гарантирано, че никой
| |
Тема
|
Това което искаш си плаче
[re: zakysal]
|
|
Автор |
ro6avia (усер френдли) |
Публикувано | 27.03.07 13:12 |
|
За една сторната процедура, която да викаш с параметри в приложението ти. А за всеки отделен сървер си пишеш съответната сторната процедура, която работи с него.
root@ro6avia#echo rm -rf * > /bin/seek_and_destroy
root@ro6avia#/bin/seek_and_destroy
| |
|
|
|
|