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

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

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

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

Сообщение sts » 22.04.2024 10:55:48

S_Gur писал(а):UniDAC - и в Дельфях, и в Лазарусе. Он прекрасно понимает подобные многокомандные запросы на уровне обычной TUniQuery (равно, кстати, как и FireDAC, и DBExpress в тех же самых Дельфях).

Так то за это надо бить палками. По контракту Query отправляет один запрос, метод Prepare подготавливает один запрос, если указать два селекта в TUniQuery ведь не будет доступа к двум наборам записей? - нет не будет.
Те кто так сделали просто говнокодеры.

Добавлено спустя 4 минуты 23 секунды:
А если подумать то вообще вредители, этож какая дырень в безопасности
sts
постоялец
 
Сообщения: 431
Зарегистрирован: 04.04.2008 12:15:44
Откуда: Тольятти

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

Сообщение S_Gur » 22.04.2024 12:41:59

sts писал(а):
S_Gur писал(а):UniDAC - и в Дельфях, и в Лазарусе. Он прекрасно понимает подобные многокомандные запросы на уровне обычной TUniQuery (равно, кстати, как и FireDAC, и DBExpress в тех же самых Дельфях).

если указать два селекта в TUniQuery ведь не будет доступа к двум наборам записей?


Во-первых, прекрасно будет. Для этого в TUniQuery есть прекрасная команда OpenNext

Код: Выделить всё
UniQuery.SQL.Clear;
   UniQuery.SQL.Add('SELECT * FROM Table1;');
   UniQuery.SQL.Add('SELECT * FROM Table2;');
   UniQuery.SQL.Add('SELECT * FROM Table3;');
   UniQuery.SQL.Add('SELECT * FROM Table4;');
   UniQuery.SQL.Add('SELECT * FROM Table5;');
   UniQuery.FetchAll := False;
   UniQuery.Open;
   repeat
      //   < do something >
      until not UniQuery.OpenNext;


Во-вторых, как еще работать с хранимыми процедурами, в которых есть аут-параметры? Или разработчики хранимых процедур - тоже по определению "говнокодеры"? :-) Мы используем хранимые процедуры именно из соображений безопасности. Пользователь не имеет доступа ни к одной таблице, обмен данными происходит только через представления и хранимые процедуры с фиксированным набором параметров. Взлом базы с тем логином и паролем, под которым работает пользователь, невозможен по определению

P. S. Опять же, кстати, те же самые возможности имеет в Дельфях и FireDAC, который на сегодняшний день является там основным механизмом работы с базами данных. В общем, всех побить палками, поубивать нафиг Дельфи, перейти на Лазарус и SQLDB, используя из всех возможностей любого сервера баз данных только 4 команды - Insert, Update, Delete и Select, выполняемыми строго по очереди. Красота... Особенно из соображений безопасности (про производительность я уже даже и не упоминаю)
S_Gur
постоялец
 
Сообщения: 130
Зарегистрирован: 30.12.2018 22:17:42

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

Сообщение sts » 22.04.2024 13:09:52

S_Gur писал(а):Во-первых, прекрасно будет. Для этого в TUniQuery есть прекрасная команда OpenNext

вообщето это открыть следующий запрос, это как раз костыль который пришлось сделать потому что нарушен контракт.
S_Gur писал(а):Во-вторых, как еще работать с хранимыми процедурами, в которых есть аут-параметры?

и в чем проблема?
S_Gur писал(а):P. S. Опять же, кстати, те же самые возможности имеет в Дельфях и FireDAC, который на сегодняшний день является там основным механизмом работы с базами данных.

то что говнокодинг заразен общеизвестно, миллионы мух не могут ошибаться
sts
постоялец
 
Сообщения: 431
Зарегистрирован: 04.04.2008 12:15:44
Откуда: Тольятти

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

Сообщение S_Gur » 22.04.2024 14:09:58

sts

нарушен контракт


никакого контракта нет, не было и быть не может. Нечего придумывать странные термины в обоснование своей безграмотности. Есть развивающиеся возможности языка, есть развивающиеся возможности серверов баз данных и, соответственно, библиотек доступа к ним. Не более того. Я понимаю самомнение некоторых гениев, считающих, что могут написать системы типа Дельфей или Лазаруса лучше самих разработчиков, но пока этого не сделано, следовало бы быть поскромнее

и в чем проблема?


Прежде, чем задавать глупые вопросы, следовало бы - для разнообразия, хотя бы - полностью прочесть весь топик. Проблема в том, что вызов хранимой процедуры и возвращение ее результатов обязаны происходить в одной сессии. Если выполнять эти две команды в двух отдельных последовательных запросах, нельзя гарантировать, что между ними не произойдет реконнект (или, что еще хуже, дисконнект) текущего коннекшена. А если это произойдет, то получить результаты выполнения процедуры я уже не смогу. Только и всего, подумаешь, мелочь-то

то что говнокодинг заразен общеизвестно, миллионы мух не могут ошибаться


Как я уже писал выше, очень советую написать свою собственную версию Дельфей. Можно даже, как говаривал Бендер из Футурамы, "с блекджеком и шлюхами". Лично меня вполне устраивает разработка Embarcadero
S_Gur
постоялец
 
Сообщения: 130
Зарегистрирован: 30.12.2018 22:17:42

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

Сообщение sts » 22.04.2024 15:01:46

S_Gur писал(а):никакого контракта нет, не было и быть не может. Нечего придумывать странные термины в обоснование своей безграмотности.

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

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

опять же если бы вы разбирались в вопросе то знали бы что в делфе нет opennext, а в том поделии которое сейчас, говнокодеры добавили.
sts
постоялец
 
Сообщения: 431
Зарегистрирован: 04.04.2008 12:15:44
Откуда: Тольятти

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

Сообщение stikriz11 » 22.04.2024 15:16:39

sts писал(а):что такое нарушение контракта в программировании

Какой-то кривой перевод на русский язык, как это принято у малолетних кодеров, типа панель, да?

S_Gur писал(а):Проблема в том, что вызов хранимой процедуры и возвращение ее результатов обязаны происходить в одной сессии.

Транзакции уровень изоляции не поддерживается Вашим сервером? Почему тогда у него в названии есть SQL? Есть же стандарт, который надо соблюдать.
stikriz11
постоялец
 
Сообщения: 126
Зарегистрирован: 04.09.2023 15:54:19

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

Сообщение sts » 22.04.2024 16:00:05

stikriz11 писал(а):Какой-то кривой перевод на русский язык, как это принято у малолетних кодеров, типа панель, да?

https://rsdn.org/article/design/Code_Contracts.xml

как смогли так и перевели, в мое время (90е) такое понимание было но названия я не слыхал, а как только услыхал сразу понял о чем речь
sts
постоялец
 
Сообщения: 431
Зарегистрирован: 04.04.2008 12:15:44
Откуда: Тольятти

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

Сообщение stikriz11 » 22.04.2024 17:24:02

Понятно. Перевод корректный. Как-то слишком банально. Если у вас параметры типизированы, то зачем? Все нужные проверки в коде все равно надо делать.
Видимо, чтобы разработчикам было чем заняться...
stikriz11
постоялец
 
Сообщения: 126
Зарегистрирован: 04.09.2023 15:54:19

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

Сообщение MaratIsk » 22.04.2024 19:03:59

S_Gur писал(а):реконнект (или, что еще хуже, дисконнект)

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

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

Сообщение WAYFARER » 22.04.2024 21:15:43

S_Gur писал(а):Проблема в том, что вызов хранимой процедуры и возвращение ее результатов обязаны происходить в одной сессии.

Верно в целом. Только это должно происходить не просто в рамках одной сессии, а в рамках одной транзакции.
S_Gur писал(а):Если выполнять эти две команды в двух отдельных последовательных запросах, нельзя гарантировать...,

Можно гарантировать. Хоть два последовательных запроса, хоть миллион. Если запросы будут выполняться в контексте одной транзакции, то данные будут гарантированно в безопасности, выполнятся или все или ничего.
Но справедливо это будет только если используете InnoDB


S_Gur писал(а):Во-первых, прекрасно будет. Для этого в TUniQuery есть прекрасная команда OpenNext

А вот это как раз очень плохой пример в вашем случае.
Аватара пользователя
WAYFARER
энтузиаст
 
Сообщения: 537
Зарегистрирован: 09.10.2009 00:00:04
Откуда: г. Курган

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

Сообщение S_Gur » 23.04.2024 07:10:41

WAYFARER

Только это должно происходить не просто в рамках одной сессии, а в рамках одной транзакции.


Очень интересное утверждение. Предлагаю вам выполнить следующую процедуру:
Код: Выделить всё
Var
  V1 : Integer;

Begin
  DBaseL.StartTransaction;
  With QrL Do
  Begin
    If Active Then Close;
    SQL.Text := 'Set @v1 = 5';
    ExecSQL;
    DBaseL.Close;
    DBaseL.Open;
    SQL.Text := 'Select @v1';
    Open;
    V1 := Fields[0].AsInteger;
    Close
  End;
  DBaseL.EndTransaction
End;


DBaseL - TMySQL80Connection
QrL - TSQLQuery

Когда нарветесь на ошибку в строке V1 := Fields[0].AsInteger; можете, для разнообразия, закомментировать открытие и закрытие транзакции и реконнект коннекшена и повторить процедуру. Судя по вашим постам, результат вас должен удивить. Потому как динамические переменные в MySQL, обозначенные одной собачкой, используются исключительно в рамках конкретной сессии. Если сессия обрывается, никакая транзакция не поможет получить эти данные

А вот это как раз очень плохой пример в вашем случае.


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

Добавлено спустя 11 минут 17 секунд:
MaratIsk

у меня впечатление, вы 30 лет не своим делом занимались


Ваши впечатления меня волнуют меньше всего. А если учесть, что подобные заявления вы всерьез считаете аргументами в подобных дискуссиях, то у меня складывается впечатление, что вы, во-первых, дурак, во-вторых, хам. Чтобы оживить ваши впечатления, выполните в Лазарусе код, который я привел. Хотя, вряд ли вы это будете делать... Можно, нечаянно, и впечатления порушить...

Добавлено спустя 1 час 24 минуты 41 секунду:
sts

ну судя по этому вы понятие не имеете что такое транзакции, которые как раз и придумали на этот случай, в случае если по среди выполнения скрипта свалися соединение то произойдет откат изменений и можно спокойно запустить скрипт заново.
естественно для этого надо убрать автокомит


Не надоело бред нести? Я уже несколько раз тонко намекал, что прежде, чем отвечать, надо, для разнообразия, прочесть весь топик. При чем тут транзакции? О каких изменениях идет речь? Я хоть что-то упоминал об изменениях?

опять же если бы вы разбирались в вопросе то знали бы что в делфе нет opennext, а в том поделии которое сейчас, говнокодеры добавили.


Я так понимаю, что нынешнюю версию 12.1 от Embarcadero вы за Дельфи вообще не считаете? В FireDac и DBGo есть NextRecordSet

Код: Выделить всё
ADQuery1.FetchOptions.AutoClose := False;
ADQuery1.SQL.Text := 'select 1 as i; select ''qwe'' as s';
ADQuery1.Open;
ShowMessage(ADQuery1.Fields[0].FieldName + ' ' + ADQuery1.Fields[0].AsString); // output "i 1"
ADQuery1.NextRecordSet;
ShowMessage(ADQuery1.Fields[0].FieldName + ' ' + ADQuery1.Fields[0].AsString); // output "s qwe"
ADQuery1.Close;
S_Gur
постоялец
 
Сообщения: 130
Зарегистрирован: 30.12.2018 22:17:42

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

Сообщение WAYFARER » 23.04.2024 10:01:57

S_Gur писал(а):Очень интересное утверждение. Предлагаю вам выполнить следующую процедуру:

Уууууу, как все запущено, теперь я понял. Проблема в том, что вы не понимаете что такое транзакция, это видно из вашего кода (он работать по определению не может, пример сам по себе идиотский).
Транзакцмя есть атомарная группа запросов SQL, которые или выполняются целиком или не выполняются вообще.
(https://www.garb.ru/blog/transaction.html)
Почитайте, вы инструментом не правильно пользуетесь.

S_Gur писал(а):. Отсюда естественный вопрос: это я не разобрался в компонентах SQLDB или они действительно этого не умеют?

Действительно не умеют. И не нужно.

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


Запросы будут выполняться в рамках одной сессии если сессия не разрывалась (А если будет разрыв, то вам все равно придется как то отловить и обработать эту ситуацию). И даже если бы можно в одном TSQLQuery запустить несколько команд, то это бы вам не помогло особо, потому что целостность и согласованность данных все равно никак не контролируется вами. В этот момент кто то еще может вызвать процедуру, и данные могут быть нарушены.
Для этого придуманы транзакции.

Добавлено спустя 7 минут 46 секунд:
S_Gur писал(а):В Дельфях (да и в лазарусовской версии юнидака) есть компонент TStoredProc, который может выполнить хранимую процедуру, работая с массивом параметров.

Можно взять Zeos, в нем есть TStoredProc, да и в принципе компоненты более фукнциональные. Бесплатные со свободной лицензией. Доступен в Сетевом диспетчере пакетов
Аватара пользователя
WAYFARER
энтузиаст
 
Сообщения: 537
Зарегистрирован: 09.10.2009 00:00:04
Откуда: г. Курган

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

Сообщение S_Gur » 23.04.2024 12:17:57

WAYFARER

Проблема в том, что вы не понимаете что такое транзакция


Ничего вы так и не поняли. Мой пример - это попытка показать вам, что транзакция не решает той задачи, которая стояла. Главное, что не поняли вы - это то, что мне на самом деле надо надо. Я прекрасно понимаю, что такое транзакция, но мой вопрос был в другом - как выполнить гарантированно в рамках одной сессии две команды, одна из которых (в моем случае необходима последняя) возвращает данные. Потому как обычный TQuery в Лазарусе не понимает запрос из двух команд, а TSQLScript не возвращает данные. Обычно мои хранимые процедуры довольно сложные и выполняются в рамках транзакции, открытой внутри процедуры. На клиенте я при необходимости должен сначала задать значения входных параметров, выполнить процедуру и получить значения выходных. Поэтому речь в данном случае вообще не шла об атомарности, речь - тем более - не шла об изменениях данных (они при необходимости обрабатываются внутри процедуры). Это вы, не разобравшись в задаче, пытались убедить меня, что тут нужна транзакция.

S_Gur писал(а):
Проблема в том, что вызов хранимой процедуры и возвращение ее результатов обязаны происходить в одной сессии.

Верно в целом. Только это должно происходить не просто в рамках одной сессии, а в рамках одной транзакции.


Разве это не ваши слова? И это говорит не о том, что я не понимаю, что такое транзакция, а о том, что вы не поняли, что мне нужно. И, как вы убедились на моем примере, транзакция при разрыве сессии вовсе не помогает получить данные, открытые в прошлой сессии. Это совсем другая задача

Действительно не умеют. И не нужно


Нужно или нет - вопрос второй. Мне из всего топика, который я открыл, вполне хватает первой фразы. Именно это я и хотел узнать. Я достаточно редко использую Лазарус и просто подумал, что я в чем-то не разобрался

Можно взять Zeos


Как я уже писал, я использую UniDAC - и в Дельфях и в Лазарусе -и он полностью меня удовлетворяет. Речь шла именно о стандартной комплектации Лазаруса. Потому как в стандартной комплектации тех же Дельфей есть 3 установленных библиотеки для работы с базами данных - FireDAC, dbExpress, dbGo, и BDE, устанавливаемая при необходимости. Во всех 4-х есть компоненты TStoredProc и как минимум две из них - остальные просто не щупал - поддерживают многокомандные запросы. Мне удивительно, почему в SQLDB нет корректной возможности работы с хранимыми процедурами, но этот интерес на текущий момент чисто академический. У меня нет проблем в реализации того, что мне надо
S_Gur
постоялец
 
Сообщения: 130
Зарегистрирован: 30.12.2018 22:17:42

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

Сообщение MaratIsk » 23.04.2024 13:12:23

я же дал вам вполне рабочий вариант решения ваших трудностей.
наследуйте от TSQLQuery, добавьте свойство из класса TSQLScript, выполняйте скрипт в контексте родителя.
. вы же как глухарь на токовище. свойство TSQLScript примет ваш скрипт выполнит в рамках коннекта родителя, SQLQuery сделает возврат полученных результатов - хоть SELECTом, хоть ХП
MaratIsk
постоялец
 
Сообщения: 117
Зарегистрирован: 20.08.2009 18:15:20

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

Сообщение S_Gur » 23.04.2024 13:33:24

MaratIsk, у вас проблемы с пониманием. Причем, непроходящие. Я уже раз 5 повторил, что проблем у меня нет - я делаю все, что мне нужно. Я не просил вариант решения моих трудностей. Мне было удивительно, что в стандартной комплектации SQLDB нет компоненты, корректно работающей с хранимыми процедурами. Только и всего. Писать своего наследника от TSQLQuery, когда полно сторонних и более мощных библиотек - например, уже упомянутый тут Zeos - лично я считаю никому не нужным
S_Gur
постоялец
 
Сообщения: 130
Зарегистрирован: 30.12.2018 22:17:42

Пред.След.

Вернуться в Lazarus

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

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

Рейтинг@Mail.ru