Выполнение SQL-скрипта с возвратом набора данных

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Выполнение SQL-скрипта с возвратом набора данных

Сообщение S_Gur » 19.04.2024 08:51:46

Доброго времени суток. База данных MySQL 8. Есть у меня необходимость выполнить скрипт из двух или нескольких команд с возвратом данных. Самый простой вариант такого скрипта - это вставка новой записи в таблицу и получение ее идентификатора, что-то типа:

Код: Выделить всё
Insert Into [TableName](...) Values(...);
Select GetLastID;


Хотел для этого воспользоваться стандартными средствами Лазаруса, без сторонних компонент. Но выяснил, что TSQLQuery в принципе не понимает скрипты из нескольких команд. Понимает TSQLScript, но навскидку я не нашел у него других методов, кроме ExecSQL. Отсюда естественный вопрос: это я не разобрался в компонентах SQLDB или они действительно этого не умеют? Вопрос на данный момент чисто теоретический, в большинстве случаев я использую UniDAC, у которого таких проблем в принципе нет, но иногда возникает потребность написания софта без использования сторонних компонент, тем более платных и дорогостоящих
S_Gur
постоялец
 
Сообщения: 130
Зарегистрирован: 30.12.2018 22:17:42

Re: Выполнение SQL-скрипта с возвратом набора данных

Сообщение MaratIsk » 19.04.2024 13:31:18

SQL-скрипт - просто набор команд. Что мешает их выполнить из приложения последовательно и сделать, например, SELECT в завершение ?! нужно ли быть для этого семи пяди по лбу ?!
MaratIsk
постоялец
 
Сообщения: 102
Зарегистрирован: 20.08.2009 18:15:20

Re: Выполнение SQL-скрипта с возвратом набора данных

Сообщение stikriz11 » 19.04.2024 13:51:53

S_Gur писал(а):без использования сторонних компонент, тем более платных и дорогостоящих

Я использую IBX. Не знаю, мне больше нравится дельфийский подход. У IBQuery есть ExecSQL. Кроме того, есть возможность на более низком уровне без компонент сделать все что угодно - без сторонних компонент и бесплатно для всех сторон.

А... MySQL... Не, такое не использую.
stikriz11
постоялец
 
Сообщения: 114
Зарегистрирован: 04.09.2023 15:54:19

Re: Выполнение SQL-скрипта с возвратом набора данных

Сообщение S_Gur » 19.04.2024 14:19:24

MaratIsk писал(а):SQL-скрипт - просто набор команд. Что мешает их выполнить из приложения последовательно и сделать, например, SELECT в завершение ?! нужно ли быть для этого семи пяди по лбу ?!


Может быть, и не нужно. Вот только 2 последовательных запроса выполняются каждый в своей сессии. В лучшем случае, я могу получить не то значение идентификатора. Кроме того, я взял самый примитивный случай. В идеале мне надо выполнить хранимую процедуру и получит выходные параметры. Что-то типа:

Код: Выделить всё
Call `prTest`(@v1, @v2, @v3, @v4);
Select @v1, @v2, Cast(@v3 As DateTime), @v4;


Короче, насчет 7 пядей во лбу - я задал конкретный вопрос. Мне надо знать, могу ли я сделать то, что мне надо, и так, как мне надо, или нет. Тем более, что, как я уже писал, тот же UniDAC это делает без проблем
S_Gur
постоялец
 
Сообщения: 130
Зарегистрирован: 30.12.2018 22:17:42

Re: Выполнение SQL-скрипта с возвратом набора данных

Сообщение MaratIsk » 19.04.2024 19:29:56

Вот только 2 последовательных запроса выполняются каждый в своей сессии - стесняюсь спросить, что за 2 запроса ? почему не 10 или, для надежности, 100 ? вы, в самом деле, работаете с базами данных?
MaratIsk
постоялец
 
Сообщения: 102
Зарегистрирован: 20.08.2009 18:15:20

Re: Выполнение SQL-скрипта с возвратом набора данных

Сообщение S_Gur » 19.04.2024 21:33:59

MaratIsk, а вы не стесняйтесь. Call `prTest`(@v1, @v2, @v3, @v4); - это первый запрос. Select @v1, @v2, Cast(@v3 As DateTime), @v4; - это второй запрос. Переменные, начинающиеся на собаку - это динамические неглобальные переменные, которые действуют только в рамках текущей сессии. В Дельфях (да и в лазарусовской версии юнидака) есть компонент TStoredProc, который может выполнить хранимую процедуру, работая с массивом параметров. В SQLDB такого нет, поэтому приходится работать таким способом - используя динамические переменные. Кстати, конструкция Insert Into [TableName](...) Values(...); Select GetLastID; - тоже, как ни странно, содержит два запроса - Insert и Select. Можно, конечно, как вы выразились, "для надежности", выполнить второй запрос 9 раз - чтобы довести до столь любимых вами 10, но лично мне вполне хватает и одного. И функция GetLastID - опять же, как ни досадно - тоже работает в рамках текущей сессии, возвращая значение вновь созданного первичного ключа вставленной записи. В другой сессии он этого значения не вернет. Да что долго ходить? Откройте в любом менеджере баз данных любую базу MySQL. Откройте два редактора запросов. В одном выполните что-нибудь типа Set @v1 = 5; Select @v1. Потом перейдите во второй редактор и выполните только Select @v1. Судя по тону, которым вы со мной общаетесь, вы будете очень удивлены результатом этого эксперимента. Так что - да, я действительно работаю с базами данных, причем уже около 30 лет - от Оракла до MySQL практически с любыми серверами

Добавлено спустя 43 минуты 36 секунд:
Как ни странно, я оказался не совсем прав. Проведенные мной эксперименты показывают, что два запроса, выполненных в рамках одного открытого коннекшена (в отличие от упомянутых мной двух редакторов запросов в любом менеджере баз данных) работают в рамках одной сессии. Тем не менее, мой вопрос остается в силе. Как минимум, потому, что коннект может по каким-то причинам временно прерваться, а реконнект точно открывает новую сессию (что тоже проверено в ходе вышеуказанных экспериментов)
S_Gur
постоялец
 
Сообщения: 130
Зарегистрирован: 30.12.2018 22:17:42

Re: Выполнение SQL-скрипта с возвратом набора данных

Сообщение MaratIsk » 20.04.2024 13:31:05

наследуйте от TSQLQuery, добавьте свойство из класса TSQLScript, выполняйте скрипт в контексте родителя. Кстати, всякие Select GetLastID я никогда не использую - получаю значение счетчика или чего еще там перед запуском пакета команд. Да и целочисленный первичный ключ практически не использую - приложения генерят GUID, который и определяет значение первичного ключа
MaratIsk
постоялец
 
Сообщения: 102
Зарегистрирован: 20.08.2009 18:15:20

Re: Выполнение SQL-скрипта с возвратом набора данных

Сообщение Sharfik » 20.04.2024 15:58:56

А так не пойдет?
Код: Выделить всё
INSERT INTO TRISKS (NAME) VALUES (:pNAME) RETURNING ID;


S_Gur писал(а):Может быть, и не нужно. Вот только 2 последовательных запроса выполняются каждый в своей сессии. В лучшем случае, я могу получить не то значение идентификатора. Кроме того, я взял самый примитивный случай. В идеале мне надо выполнить хранимую процедуру и получит выходные параметры. Что-то типа:

Для этого есть транзакции и их подтверждение. Будет изолированная область обрабатываться.
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 768
Зарегистрирован: 20.07.2013 01:04:30

Re: Выполнение SQL-скрипта с возвратом набора данных

Сообщение MaratIsk » 20.04.2024 16:11:21

у скриптовых компонентов нет буфера для хранения набора данных. не знаю, что вы программировали 30 лет, но многие вещи для вас, как я догадываюсь, внове. особенно, ваши эксперименты с connections
MaratIsk
постоялец
 
Сообщения: 102
Зарегистрирован: 20.08.2009 18:15:20

Re: Выполнение SQL-скрипта с возвратом набора данных

Сообщение Sharfik » 20.04.2024 18:51:15

Ты кому отвечаешь хоть пиши
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 768
Зарегистрирован: 20.07.2013 01:04:30

Re: Выполнение SQL-скрипта с возвратом набора данных

Сообщение S_Gur » 20.04.2024 20:56:06

Sharfik писал(а):А так не пойдет?
Код: Выделить всё
INSERT INTO TRISKS (NAME) VALUES (:pNAME) RETURNING ID;


К сожалению, не пойдет. Пример с инсертом - это просто примитивный пример для скрипта, содержащего две команды. В нашем проекте около полутора сотен хранимых процедур. В общем случае, мои запросы выглядят примерно так:

Код: Выделить всё
Set @v1 = 5; Set @v2 = 'qwern'; Set @v3 = False; Call `prProc`(@v1, @v2, @v3, @vResult); Select @vResult;


Это тоже один из самых простых примеров. В нем возвращается только код результата выполнения процедуры. Во многих случаях оут-параметров несколько, поэтому на выходе получаем что-то типа:

Код: Выделить всё
Select @v4, @v5, @v6, @vResult


В общем, как я уже писал, спор глупый и беспочвенный. Я использую UniDAC - и в Дельфях, и в Лазарусе. Он прекрасно понимает подобные многокомандные запросы на уровне обычной TUniQuery (равно, кстати, как и FireDAC, и DBExpress в тех же самых Дельфях). В последней версии UniDAC я обнаружил небольшой баг и сделал тестовый проект для отправки, в котором выполнил одну и ту же операцию с UniDAC и другими компонентами работы с MySQL. Когда я делал такой проект в Лазарусе, я наткнулся на это ограничение и решил, что, вполне возможно, чего-то о SQLDB не знаю я. В общем-то, никакой проблемы у меня нет, поэтому тему считаю закрытой

Добавлено спустя 3 минуты 24 секунды:
MaratIsk писал(а):у скриптовых компонентов нет буфера для хранения набора данных. не знаю, что вы программировали 30 лет, но многие вещи для вас, как я догадываюсь, внове. особенно, ваши эксперименты с connections


Я не знаю, о каких скриптовых компонентах вы говорите. Я использую обычный TQuery. В последние несколько лет TUniQuery из библиотеки UniDAC. Так что, вы можете догадываться о чем угодно, но у меня все прекрасно работает
S_Gur
постоялец
 
Сообщения: 130
Зарегистрирован: 30.12.2018 22:17:42

Re: Выполнение SQL-скрипта с возвратом набора данных

Сообщение MaratIsk » 21.04.2024 05:17:52

S_Gur писал(а):Хотел для этого воспользоваться стандартными средствами Лазаруса, без сторонних компонент. Но выяснил, что TSQLQuery в принципе не понимает скрипты из нескольких команд. Понимает TSQLScript, но навскидку я не нашел у него других методов, кроме ExecSQL

вы уж определитесь с чем работаете
MaratIsk
постоялец
 
Сообщения: 102
Зарегистрирован: 20.08.2009 18:15:20

Re: Выполнение SQL-скрипта с возвратом набора данных

Сообщение Снег Север » 21.04.2024 05:37:28

MaratIsk писал(а):вы уж определитесь с чем работаете

Топикстартер внятно сказал, что его не устраивает. А некоторые читают явно не головой.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2997
Зарегистрирован: 27.11.2007 16:14:47

Re: Выполнение SQL-скрипта с возвратом набора данных

Сообщение MaratIsk » 21.04.2024 07:12:28

Снег Север писал(а):
MaratIsk писал(а):вы уж определитесь с чем работаете

Топикстартер внятно сказал, что его не устраивает. А некоторые читают явно не головой.

с бодуна что ли ?! цитату видел?
MaratIsk
постоялец
 
Сообщения: 102
Зарегистрирован: 20.08.2009 18:15:20

Re: Выполнение SQL-скрипта с возвратом набора данных

Сообщение Sharfik » 21.04.2024 19:46:19

Снег Север писал(а):А некоторые читают явно не головой.

:lol:
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 768
Зарегистрирован: 20.07.2013 01:04:30

След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 15

Рейтинг@Mail.ru