powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Получение последней вставленной записи ( last_insert_id)
25 сообщений из 31, страница 1 из 2
Получение последней вставленной записи ( last_insert_id)
    #38792688
miv32
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!

Нашел изящное решение от В.Максимова для получения последней вставленной записи в таблицу на сервере.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Всё оказалось достаточно просто. Нужно при помощи SQLEXEC добавлять запись непосредственно в таблицу на сервере,
одновременно получая значение SCOPE_IDENTITY(), потом обновлять курсор и позиционироваться на запись с полученным ID: 
  
  lcCmd = 'INSERT INTO tablename (Field1, ....) VALUES (?var1, ?...) SELECT SCOPE_IDENTITY() as newid'  
  lnResult = SQLEXEC(oCA.DataSource, lcCmd, '_Cur_id')  
  IF lnResult = 1  
     oCA.CursorRefresh()  
     SEEK _cur_id.newid ORDER TAG tagname IN cursorname   
     USE IN _cur_id  
  ENDIF



Для MySql такая конструкция не работает. Или я не прав?
...
Рейтинг: 0 / 0
Получение последней вставленной записи ( last_insert_id)
    #38792744
Sergey Sizov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miv32Добрый день!

Нашел изящное решение от В.Максимова для получения последней вставленной записи в таблицу на сервере.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Всё оказалось достаточно просто. Нужно при помощи SQLEXEC добавлять запись непосредственно в таблицу на сервере,
одновременно получая значение SCOPE_IDENTITY(), потом обновлять курсор и позиционироваться на запись с полученным ID: 
  
  lcCmd = 'INSERT INTO tablename (Field1, ....) VALUES (?var1, ?...) SELECT SCOPE_IDENTITY() as newid'  
  lnResult = SQLEXEC(oCA.DataSource, lcCmd, '_Cur_id')  
  IF lnResult = 1  
     oCA.CursorRefresh()  
     SEEK _cur_id.newid ORDER TAG tagname IN cursorname   
     USE IN _cur_id  
  ENDIF



Для MySql такая конструкция не работает. Или я не прав?Какая ТАКАЯ? В приведенном коде куча конструкций.
Есть в MySQL функция SCOPE_IDENTITY()?
...
Рейтинг: 0 / 0
Получение последней вставленной записи ( last_insert_id)
    #38792767
miv32
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Команда типа такой:
lcCmd = 'INSERT INTO tablename (Field1, ....) VALUES (?var1, ?...) SELECT SCOPE_IDENTITY() as newid'

В MySql аналог SCOPE_IDENTITY() - LAST_INSERT_ID()

Код: sql
1.
2.
3.
4.
5.
6.
TEXT TO lcCmd NOSHOW
INSERT INTO testtable (id_name) VALUES ('vefwdwduwe') SELECT LAST_INSERT_ID() as newid
ENDTEXT

= SQLEXEC(thisform.lnconnection, lcCmd, '_Cur_id')
Возвращает  -1
...
Рейтинг: 0 / 0
Получение последней вставленной записи ( last_insert_id)
    #38792789
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miv32
Код: sql
1.
Возвращает  -1


Дальше смотри ошибку через AERROR()
...
Рейтинг: 0 / 0
Получение последней вставленной записи ( last_insert_id)
    #38792805
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miv32, там надо 2 запроса - первый на инсерт, второй на селект. Объединённой команды в мускле нет, увы.
...
Рейтинг: 0 / 0
Получение последней вставленной записи ( last_insert_id)
    #38792806
Jura.K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

Делать два отдельных запроса
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
TEXT TO lcCmd NOSHOW
  INSERT INTO testtable (id_name) VALUES ('vefwdwduwe') 
ENDTEXT

TEXT TO lcLastID NOSHOW
  SELECT LAST_INSERT_ID() as newid
ENDTEXT

= SQLEXEC(thisform.lnconnection, lcCmd)
= SQLEXEC(thisform.lnconnection, lcLastID, '_Cur_id')



Или еще лучше прописать функцию на сервере
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
CREATE DEFINER = 'root'@'127.0.0.1'
FUNCTION ugstat.NewID()
  RETURNS varchar(25) CHARSET cp1251
BEGIN
DECLARE NewID varchar(25) ;
INSERT INTO testtable (id_name) VALUES ('vefwdwduwe') ;
 
SELECT LAST_INSERT_ID() INTO NewID ;

RETURN NewId ;
END
...
Рейтинг: 0 / 0
Получение последней вставленной записи ( last_insert_id)
    #38792815
miv32
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
LOCAL aErrorLog[1,7], lcCmd, res

TEXT TO lcCmd NOSHOW
INSERT INTO testtable (id_name) VALUES ('veadasdsdwe') SELECT LAST_INSERT_ID() as newid
ENDTEXT


m.res = SQLEXEC(thisform.lnconnection,lcCmd,'_Cur_id') 
IF m.res < 0
	aerror(aErrorLog)

SET TEXTMERGE ON 
SET CONSOLE OFF
SET TEXTMERGE TO c:\qqq.txt

	FOR i = 1 TO ALEN(aErrorLog,1)
		\<<aErrorLog(i,1)>>     <<aErrorLog(i,2)>>     <<aErrorLog(i,3)>>     <<aErrorLog(i,4)>>     <<aErrorLog(i,5)>>     <<aErrorLog(i,6)>>     <<aErrorLog(i,7)>>
	ENDFOR

SET TEXTMERGE OFF 
SET CONSOLE ON
SET TEXTMERGE TO
ENDIF



1526 Connectivity error: [MySQL][ODBC 5.3(a) Driver][mysqld-5.5.5-10.0.14-MariaDB]You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'SELECT LAST_INSERT_ID() as newid' at line [MySQL][ODBC 5.3(a) Driver][mysqld-5.5.5-10.0.14-MariaDB]You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'SELECT LAST_INSERT_ID() as newid' at line 1 37000 1064 3
...
Рейтинг: 0 / 0
Получение последней вставленной записи ( last_insert_id)
    #38792818
Jura.K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
функцию можно вызвать
Код: sql
1.
= SQLEXEC(thisform.lnconnection, 'SELECT NEW_ID() AS newID','_Cur_id')
...
Рейтинг: 0 / 0
Получение последней вставленной записи ( last_insert_id)
    #38792820
miv32
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Можно, конечно, сделать 2 SQLEXEC подряд. Но это уже чревато. Система же многопользовательская.
Придется, значит, строить CursorAdapter.
...
Рейтинг: 0 / 0
Получение последней вставленной записи ( last_insert_id)
    #38792823
miv32
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Про функцию как обертку я думал.
Но это придется каждый insert оборачивать.
...
Рейтинг: 0 / 0
Получение последней вставленной записи ( last_insert_id)
    #38792826
Jura.K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что значит многопользовательска
в пределах одной сессии LAST_INSERT_ID возвращает только значение полученное в результате вставки именно в этой сессии
и ни какие другие коннекты не влияют вы же не меняете хендл подключения
...
Рейтинг: 0 / 0
Получение последней вставленной записи ( last_insert_id)
    #38792835
Jura.K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Поясню
имеем 2 пользователя
каждый имеет свой хендл подключения (да даже если это одна программа запущенная с одного компьютера но имеет два хендела подключения)
Код: sql
1.
2.
nHandle1=SQLSTRINGCONNECT(.....)
nHandle2=SQLSTRINGCONNECT(.....)



один вставляет значение 123

Код: sql
1.
=SQLEXEC(nHandle1, 'INSERT INTO tbl1 (pole1) VALUES (123)')


второй вставляет значение 245

Код: sql
1.
=SQLEXEC(nHandle2, 'INSERT INTO tbl1 (pole1) VALUES (245)')


После этого можете в любом порядке запрашивать
Код: sql
1.
=SQLEXEC(nHandle1, 'SELECT LAST_INSERT_ID()')

вернет 123
Код: sql
1.
=SQLEXEC(nHandle2, 'SELECT LAST_INSERT_ID()')

вернет 245

можете еще раз запросить
Код: sql
1.
=SQLEXEC(nHandle1, 'SELECT LAST_INSERT_ID()')

все равно вернет 123

Все будет зависеть от того по какому Хендлу подключения идет запрос
...
Рейтинг: 0 / 0
Получение последней вставленной записи ( last_insert_id)
    #38792852
Sergey Sizov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miv32Команда типа такой:
lcCmd = 'INSERT INTO tablename (Field1, ....) VALUES (?var1, ?...) SELECT SCOPE_IDENTITY() as newid'

В MySql аналог SCOPE_IDENTITY() - LAST_INSERT_ID()

Код: sql
1.
2.
3.
4.
5.
6.
TEXT TO lcCmd NOSHOW
INSERT INTO testtable (id_name) VALUES ('vefwdwduwe') SELECT LAST_INSERT_ID() as newid
ENDTEXT

= SQLEXEC(thisform.lnconnection, lcCmd, '_Cur_id')
Возвращает  -1

А MySql позволяет писать команды без разделителей? Или Вы посчитали приведенную конструкцию одной командой? Если так, то сильно ошибаетесь.
Попробуйте так:
Код: sql
1.
lcCmd = 'INSERT INTO tablename (Field1, ....) VALUES (?var1, ?...); SELECT LAST_INSERT_ID() as newid'
...
Рейтинг: 0 / 0
Получение последней вставленной записи ( last_insert_id)
    #38792896
Jura.K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sergey Sizov,

Так тоже будет ошибка, работа ведь идет через ODBC

Я уже предложил два варианта
1. два запроса при одном хендле
2. мудрить функцию или процедуру (с передачей параметров)
...
Рейтинг: 0 / 0
Получение последней вставленной записи ( last_insert_id)
    #38792950
Sergey Sizov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Jura.KSergey Sizov,

Так тоже будет ошибка, работа ведь идет через ODBCИ при чем тут это? Запрос исполняет сервер, а не драйвер. То, что мелкомягкий сервер допускает опускание разделителей команд, то совсем не факт, что такое же допускают и другие серверы. Именно об этом и был спич.
...
Рейтинг: 0 / 0
Получение последней вставленной записи ( last_insert_id)
    #38792968
miv32
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Респект! :)

INSERT INTO testtable (id_name) VALUES ('vea3373dwe'); select LAST_INSERT_ID() РАБОТАЕТ!

; спасет гиганта мысли.
...
Рейтинг: 0 / 0
Получение последней вставленной записи ( last_insert_id)
    #38797229
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miv32Можно, конечно, сделать 2 SQLEXEC подряд. Но это уже чревато. Система же многопользовательская.почему, бл***, ни один человек, впервые услышавший про ласт_инсерт_ид, не удосуживается прочитать факинговую справку по этой функции? :(
Sergey SizovА MySql позволяет писать команды без разделителей?Нет. А в настройках одбц надо ещё включить мультистэйтмент (ЕМНИП он по умолчанию отключен).
Jura.KТак тоже будет ошибка, работа ведь идет через ODBCSergey SizovТо, что мелкомягкий сервер допускает опускание разделителей команд, то совсем не факт, что такое же допускают и другие серверы.см.выше
...
Рейтинг: 0 / 0
Получение последней вставленной записи ( last_insert_id)
    #38802634
miv32
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Рано радовался. :(

INSERT INTO tablename (Field1, ....) VALUES (?var1, ?...); SELECT LAST_INSERT_ID() as newid
на серваке через клиента типа TOAD и HeidiSql отрабатывает.

А в фоксе через SQLEXEC не хочет.
Убираешь ; SELECT LAST_INSERT_ID() as newid - работает.

Или я туплю?
...
Рейтинг: 0 / 0
Получение последней вставленной записи ( last_insert_id)
    #38802930
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miv32А в фоксе через SQLEXEC не хочет.

Сообщение об ошибке мы увидим?
PS. multiple statements вы в настройках одбц включили или нет?
...
Рейтинг: 0 / 0
Получение последней вставленной записи ( last_insert_id)
    #38802951
miv32
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Как его включать?
У меня параметры соединения прописаны в строке

lcDSN="DRIVER=MySQL ODBC 5.3 ANSI Driver;"+;
"UID=<юзер>;"+;
"STMT=;"+;
"OPTION=16;"+;
"PASSWORD=<пароль>;"+;
"SERVER=<ip-шник>;"+;
"DATABASE=<база>;"+;
"DESC="

PUBLIC pnConnHandle

pnConnHandle = SQLSTRINGCONNECT(lcDSN,.T.)
...
Рейтинг: 0 / 0
Получение последней вставленной записи ( last_insert_id)
    #38802953
miv32
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Connectivity error: [MySQL][ODBC 5.3(a) Driver][mysqld-5.5.5-10.0.14-MariaDB]You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'SELECT LAST_INSERT_ID() as newid' at line [MySQL][ODBC 5.3(a) Driver][mysqld-5.5.5-10.0.14-MariaDB]
...
Рейтинг: 0 / 0
Получение последней вставленной записи ( last_insert_id)
    #38803092
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miv32Как его включать?Вот здесьmiv32"OPTION=16;"+;выставить нужное число. Как его узнать? Пуск-администрирование-источники данных одбц, создать файловый dsn, натыкать в окне настроек нужных галочек (в т.ч. и мультистэйтмент), протестировать соединение, сохранить. Потом открыть созданный dsn как текстовый файл и посмотреть нужное значение OPTION. Можно, конечно, по манам пошариться на предмет какой бит чему там соответствует, но это дольше будет :)
...
Рейтинг: 0 / 0
Получение последней вставленной записи ( last_insert_id)
    #38803152
miv32
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Еще бы знать, где лежит этот файловый DSN...
...
Рейтинг: 0 / 0
Получение последней вставленной записи ( last_insert_id)
    #38803210
Jura.K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот описание

1 FLAG_FIELD_LENGTH Do not Optimize Column Width The client cannot handle that Connector/ODBC returns the real width of a column. This option was removed in 3.51.18.
2 FLAG_FOUND_ROWS Return Matching Rows The client cannot handle that MySQL returns the true value of affected rows. If this flag is set, MySQL returns “found rows” instead. You must have MySQL 3.21.14 or newer to get this to work.
4 FLAG_DEBUG Trace Driver Calls To myodbc.log Make a debug log in C:\myodbc.log on Windows, or /tmp/myodbc.log on Unix variants. This option was removed in Connector/ODBC 3.51.18.
8 FLAG_BIG_PACKETS Allow Big Results Do not set any packet limit for results and bind parameters. Without this option, parameter binding will be truncated to 255 characters.
16 FLAG_NO_PROMPT Do not Prompt Upon Connect Do not prompt for questions even if driver would like to prompt.
32 FLAG_DYNAMIC_CURSOR Enable Dynamic Cursor Enable or disable the dynamic cursor support.
64 FLAG_NO_SCHEMA Ignore # in Table Name Ignore use of database name in db_name.tbl_name.col_name.
128 FLAG_NO_DEFAULT_CURSOR User Manager Cursors Force use of ODBC manager cursors (experimental).
256 FLAG_NO_LOCALE Do not Use Set Locale Disable the use of extended fetch (experimental).
512 FLAG_PAD_SPACE Pad Char To Full Length Pad CHAR columns to full column length.
1024 FLAG_FULL_COLUMN_NAMES Return Table Names for SQLDescribeCol SQLDescribeCol() returns fully qualified column names.
2048 FLAG_COMPRESSED_PROTO Use Compressed Protocol Use the compressed client/server protocol.
4096 FLAG_IGNORE_SPACE Ignore Space After Function Names Tell server to ignore space after function name and before “(” (needed by PowerBuilder). This makes all function names keywords.
8192 FLAG_NAMED_PIPE Force Use of Named Pipes Connect with named pipes to a mysqld server running on NT.

16384 FLAG_NO_BIGINT Change BIGINT Columns to Int Change BIGINT columns to INT columns (some applications cannot handle BIGINT).

32768 FLAG_NO_CATALOG No Catalog Forces results from the catalog functions, such as SQLTables, to always return NULL and the driver to report that catalogs are not supported.
65536 FLAG_USE_MYCNF Read Options From my.cnf Read parameters from the [client] and [odbc] groups from my.cnf.
131072 FLAG_SAFE Safe Add some extra safety checks.
262144 FLAG_NO_TRANSACTIONS Disable transactions Disable transactions.
524288 FLAG_LOG_QUERY Save queries to myodbc.sql Enable query logging to c:\myodbc.sql(/tmp/myodbc.sql) file. (Enabled only in debug mode.)
1048576 FLAG_NO_CACHE Do not Cache Result (forward only cursors) Do not cache the results locally in the driver, instead read from server (mysql_use_result()). This works only for forward-only cursors. This option is very important in dealing with large tables when you do not want the driver to cache the entire result set.
2097152 FLAG_FORWARD_CURSOR Force Use Of Forward Only Cursors Force the use of Forward-only cursor type. In case of applications setting the default static/dynamic cursor type, and one wants the driver to use noncache result sets, then this option ensures the forward-only cursor behavior.
4194304 FLAG_AUTO_RECONNECT Enable auto-reconnect. Enables auto-reconnection functionality. You should not use this option with transactions, since a auto reconnection during a incomplete transaction may cause corruption. Note that an auto-reconnected connection will not inherit the same settings and environment as the original. This option was added in Connector/ODBC 3.51.13.
8388608 FLAG_AUTO_IS_NULL Flag Auto Is Null When FLAG_AUTO_IS_NULL is set, the driver does not change the default value of sql_auto_is_null, leaving it at 1, so you get the MySQL default, not the SQL standard behavior.
When FLAG_AUTO_IS_NULL is not set, the driver changes the default value of SQL_AUTO_IS_NULL to 0 after connecting, so you get the SQL standard, not the MySQL default behaviour.
Thus, omitting the flag disables the compatibility option and forces SQL standard behaviour.
See IS NULL. This option was added in Connector/ODBC 3.51.13.
16777216 FLAG_ZERO_DATE_TO_MIN Flag Zero Date to Min Translates zero dates (XXXX-00-00) into the minimum date values supported by ODBC, XXXX-01-01. This resolves an issue where some statements will not work because the date returned and the minimum ODBC date value are incompatible. This option was added in Connector/ODBC 3.51.17.
33554432 FLAG_MIN_DATE_TO_ZERO Flag Min Date to Zero Translates the minimum ODBC date value (XXXX-01-01) to the zero date format supported by MySQL (XXXX-00-00). This resolves an issue where some statements will not work because the date returned and the minimum ODBC date value are incompatible. This option was added in Connector/ODBC 3.51.17.
67108864 FLAG_MULTI_STATEMENTS Allow multiple statements Enables support for batched statements. This option was added in Connector/ODBC 3.51.18.
134217728 FLAG_COLUMN_SIZE_S32 Limit column size to 32-bit value Limits the column size to a signed 32-bit value to prevent problems with larger column sizes in applications that do not support them. This option is automatically enabled when working with ADO applications. This option was added in Connector/ODBC 3.51.22.
268435456 FLAG_NO_BINARY_RESULT Always handle binary function results as character data When set this option disables charset 63 for columns with an empty org_table. This option was added in Connector/ODBC 3.51.26.

Из чего следует что OPTION = 67108864
...
Рейтинг: 0 / 0
Получение последней вставленной записи ( last_insert_id)
    #38803236
miv32
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
O! То что надо! :) Спасибо!
Чувствуется, товарищ, который это собирал, изрядно потрудился.
В MySql-ной доке ни черта толком не найдешь.
Убогий поиск, который на Оракловый сайт выкидывает да еще + с кучей ссылок.
Откуда вот узнать, что синтаксис именно такой?
Что если надо несколько OPTION, то нужные просто складывать.

И все таки - где лежит файлик, в который настройки ODBC валяться, если я в диалоговом окошке натыкал мышкой нужные параметры?
...
Рейтинг: 0 / 0
25 сообщений из 31, страница 1 из 2
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Получение последней вставленной записи ( last_insert_id)
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]