Как передавать null в параметр запроса?

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

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

Re: Как передавать null в параметр запроса?

Сообщение zoltanleo » 07.03.2019 17:08:13

jsa писал(а):Удивляет больше, почему в языке который так популярен для написания ковырялок в базах данных не реализована нормальная поддержка "неопределенного значения" для всех типов данных.

Как обычно, плохому танцору гвозди на сцене мешают :)

Твое "решение проблемы" - это костыль дилетанта, причем не очень изящный (вот интересно, если у тебя pID окажется null'ом, че тогда делать будешь? Параметр у тебя останется без значения. В приведенном тобой "решении" этот казус никак не разрешается). Обычно применяются универсальные решения, если таковые имеются. Применительно к IDE и ЯП, это присвоение вариантного значения свойству Value параметра, о чем и было сказано в первых постах топика. И если она тебе не показалась "нормальной", то это твои проблемы, а не языка.
Аватара пользователя
zoltanleo
постоялец
 
Сообщения: 273
Зарегистрирован: 17.10.2013 10:55:01

Re: Как передавать null в параметр запроса?

Сообщение jsa » 08.03.2019 07:34:50

zoltanleo писал(а):Как обычно, плохому танцору гвозди на сцене мешают :)
Твое "решение проблемы" - это костыль дилетанта, причем не очень изящный

Я так понимаю, что ты танцуешь очень изящно, и тебе не мешают ни гвозди ни, что либо другое (по причине отсутствия и того и другого).
(вот интересно, если у тебя pID окажется null'ом, че тогда делать будешь? Параметр у тебя останется без значения. В приведенном тобой "решении" этот казус никак не разрешается).

Дяденька, вы НЕ умный?
"че тогда буду делать?" Радоваться буду, т.к. все работает как надо. Параметр без значения в SQL запросе, получает значение NULL , ровно то что требуется.
А вам советую прежде чем задавать глупые вопросы, таки проверить останется параметр без значения (т.е. выдается ошибка), или таки будет иметь значение NULL, т.е. ровно такое какое ожидается.

Обычно применяются универсальные решения, если таковые имеются. Применительно к IDE и ЯП, это присвоение вариантного значения свойству Value параметра, о чем и было сказано в первых постах топика. И если она тебе не показалась "нормальной", то это твои проблемы, а не языка.

Танцор, тебе надо читать научиться. Проблема языка есть, в типах не предусмотрено неопределенное значение которым можно оперировать. И если тебе это кажется "нормальным", то это твоя проблема.
jsa
новенький
 
Сообщения: 68
Зарегистрирован: 28.11.2017 13:46:04

Re: Как передавать null в параметр запроса?

Сообщение Лекс Айрин » 08.03.2019 08:02:06

zoltanleo, вообще-то предусмотрено. Это и есть null. Или тебе нужна такая же абстракция как положительный/отрицательный ноль? формально ее можно считать либо отдельным типом, либо переменной с таким же значением. Так как паскаль язык со строгой типизацией, то проще считать второе, что не мешает, так как тип фактически тоже переменная.
И зря ты наезжаешь. В твоём случае действительно лучше использовать стандартные средства языка типа множеств. И одним из вариантов считать null. Я вон точно также спорил с Zub-ом, и потом пришлось с ним согласиться. Заодно он показал несколько трюков настоящего программиста. Сейчас же ты идешь к тому, что тебя будут игнорить. Тупо не отвечать на вопросы.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5307
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Как передавать null в параметр запроса?

Сообщение zoltanleo » 08.03.2019 10:27:30

Лекс Айрин писал(а):zoltanleo, вообще-то предусмотрено. Это и есть null.

код ТС'а
Код: Выделить всё
if pID<>null then ParamByName('pID').AsInteger:= pID;

сравним по нелепости разве что только с
Код: Выделить всё
if BooleanVar = True then ...

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

Про отправку NULL'а в качестве значения на сервер, тут да, я немного ступил: проблемы будут, только если поле not null и нет триггера, обрабатывающего соответствующую ситуацию.

зы. давно зарекся школьнегам не помогать, поди ж ты, случаются казусы.
Аватара пользователя
zoltanleo
постоялец
 
Сообщения: 273
Зарегистрирован: 17.10.2013 10:55:01

Re: Как передавать null в параметр запроса?

Сообщение jsa » 08.03.2019 15:35:15

zoltanleo писал(а):зы. давно зарекся школьнегам не помогать, поди ж ты, случаются казусы.

Зарекись высказывать презрение к тому кому "помогаешь", и учись излагать свои мысли.
Списать на "школьника" очень просто. Вот только я не школьник, и не я про танцора, как типичная школота, нахамил.


Вопрос по существу (профессионала не желающего помогать дилетантской-школоте просьба не беспокоиться)

Если код в стиле
Код: Выделить всё
if pID<>null then ParamByName('pID').AsInteger:= pID;

жутко нелеп, для языка Pascal в котором всё строго и есть всё необходимое чтобы обрабатывать NULL , и рекомендуется не использовать AsInteger или AsDateTime и т.д., то в таком случае как компилятор определяет какого типа должен быть параметр FFF ?

Код: Выделить всё
Var DDD:variant
begin
   SQLquery1.Open; SQLquery1.First;
   DDD:=SQLquery1.FieldValue['DDD'];
   ...
   SQLquery2.SQL.Text:= sqltxt ; //тест скрипта берется из базы
   SQLquery2.ParamByName('FFF').Value:=DDD
   SQLquery2.ExecSQL
end



В тесте скрипта нет никакого намека на тип переменной в которую подается параметр, например это параметр в вызов хранимой процедуры.
exec test_script @fff = :FFF

Как компилятор определяет какого типа должен быть параметр FFF ?
Это может быть строка, дробное число или вообще datatime. И может принимать значение NULL.

Кто-нибудь может дилетанту и без высказывания презрения, объяснить как это будет работать?
jsa
новенький
 
Сообщения: 68
Зарегистрирован: 28.11.2017 13:46:04

Re: Как передавать null в параметр запроса?

Сообщение Снег Север » 08.03.2019 15:45:53

jsa писал(а):Кто-нибудь может дилетанту и без высказывания презрения, объяснить как это будет работать?

Намекаю, что исходники открытые и посмотреть в них реализацию variant никому не запрещается.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 1740
Зарегистрирован: 27.11.2007 16:14:47

Re: Как передавать null в параметр запроса?

Сообщение Vadim » 08.03.2019 15:58:15

jsa писал(а):Кто-нибудь может дилетанту и без высказывания презрения, объяснить как это будет работать?

А прямо в базе это ни в коем случае нельзя реализовать? Обязательно это значение наружу вытаскивать?
Vadim
долгожитель
 
Сообщения: 3466
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Как передавать null в параметр запроса?

Сообщение Дож » 08.03.2019 16:00:17

Как компилятор определяет какого типа должен быть параметр FFF ?

variant представляет из себя пару <тип,значние>. SQLquery2.ParamByName('FFF') возвращает TParam, у которого свойство Value имеет тип variant. Оператор присваивания
Код: Выделить всё
SQLquery2.ParamByName('FFF').Value:=DDD

копирует тип и значение из DDD в соответствующее поле, см. SetAsVariant
Код: Выделить всё
Procedure TParam.SetAsVariant(const AValue: Variant);
begin
  FValue:=AValue;
  FBound:=not VarIsClear(AValue);
  if FDataType = ftUnknown then
    case VarType(Value) of
      varBoolean  : FDataType:=ftBoolean;
      varSmallint,
      varShortInt,
      varByte     : FDataType:=ftSmallInt;
      varWord,
      varInteger  : FDataType:=ftInteger;
      varCurrency : FDataType:=ftCurrency;
      varLongWord,
      varSingle,
      varDouble   : FDataType:=ftFloat;
      varDate     : FDataType:=ftDateTime;
      varString,
      varOleStr   : if (FDataType<>ftFixedChar) then
                      FDataType:=ftString;
      varInt64    : FDataType:=ftLargeInt;
    else
      if VarIsFmtBCD(Value) then
        FDataType:=ftFmtBCD
      else if VarIsArray(AValue) and (VarType(AValue) and varTypeMask = varByte) then
        FDataType:=ftVarBytes
      else
        FDataType:=ftUnknown;
    end;
end;
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 756
Зарегистрирован: 12.10.2008 16:14:47

Re: Как передавать null в параметр запроса?

Сообщение Лекс Айрин » 08.03.2019 16:18:57

jsa, вообще-то приведенный тобой пример условного оператора вполне логичен. Приведение типа требуется довольно часто. Другое дело, что это можно сделать и другими методами, например, используя absolute. В случае с null сложность в том, что это фактически неопределенное значение, которое можно представить разве что флагом и поэтому соответственно, присвоить его чему либо сложно. Я не знаю, как это представлено в ближайшее, но подозреваю как обычная текстовая строка. Ну или, допустим, экзотикой типа отрицательный ноль.
В принципе, null можно обрабатывать как ошибку обычным case в ветке else. Понятно, что это жутко неудобно, но куда деваться.
jsa, все просто. Тип определяется ещё на этапе компиляции по записям в служебных таблицах. Поэтому можно извращаться даже с простыми конструкциями, которые невозможно представить в командах и регистрах процессора
Снег Север, да не будут они смотреть. Это слишком просто. Поэтому, им даже исходники можно не цитировать.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5307
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Как передавать null в параметр запроса?

Сообщение jsa » 08.03.2019 16:21:08

Vadim писал(а):А прямо в базе это ни в коем случае нельзя реализовать? Обязательно это значение наружу вытаскивать?

Этож просто примитивный пример,для иллюстрации.

Добавлено спустя 6 минут 25 секунд:
Дож писал(а):variant представляет из себя пару <тип,значние>. ... Оператор присваивания копирует тип и значение из DDD в соответствующее поле,

Спасибо.
jsa
новенький
 
Сообщения: 68
Зарегистрирован: 28.11.2017 13:46:04

Re: Как передавать null в параметр запроса?

Сообщение Vadim » 08.03.2019 16:48:34

jsa писал(а):Этож просто примитивный пример,для иллюстрации.

Крайне неудачный пример. Может всё-таки попробуете подобрать что-то более приближенное к жизни? ;-)
Простите, если Вас обижу, но то, что Вы привели для примера в данном случае показывает - Вам просто нужно количество кода на Паскале увеличить...
Vadim
долгожитель
 
Сообщения: 3466
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Как передавать null в параметр запроса?

Сообщение jsa » 08.03.2019 16:58:37

Лекс Айрин писал(а):...

Спасибо
Лекс Айрин писал(а):да не будут они смотреть. Это слишком просто. Поэтому, им даже исходники можно не цитировать.

Они смотрят, они нужную информацию извлечь не могут.

Добавлено спустя 56 минут 36 секунд:
Vadim писал(а):
jsa писал(а):Этож просто примитивный пример,для иллюстрации.

Крайне неудачный пример. Может всё-таки попробуете подобрать что-то более приближенное к жизни? ;-)

Вам жЫзненных примеров? Их есть у меня.

Существует такой приказ 302н "Об утверждении перечней вредных и (или) опасных производственных факторов и работ, при выполнении которых проводятся обязательные предварительные и периодические медицинские осмотры (обследования), и Порядка проведения обязательных предварительных и периодических медицинских осмотров (обследований) работников, занятых на тяжелых работах и на работах с вредными и (или) опасными условиями труда"
http://www.consultant.ru/document/cons_doc_LAW_120902/

1. Приказ состоит из перечня факторов и работ.
2. каждый фактор и работа состоят из "мероприятий"
3. "Мероприятия" бывают обязательные и "по показаниям"
4. "Мероприятие" может быть консультацией специалиста, лабораторным анализом, частью лабораторного анализа(параметр биохимии например), инструментальным ииследованием.
5. Обследуемый приносит направление в котором могут быть перечислены от 1 до N факторов и работ
6. В итоге составляется "профосмотровый маршрут", составляется как пересечение множеств мероприятий входящих в поданный список факторов и работ. Маршрут пациента в итоге состоит от 10 до 20 мероприятий, иногда и 30
7. В разных клиниках 1 конекретное Мероприятие включают в себя 1 Направление и от 1 до X услуг прайса.
8. Часть услуг могут быть оплачены за счет предприятия, часть за счет пациента.
9. Мероприятия - лабораторные анализы включенные в профмаршрут, должны быть объединены в один(несколько) по типу забираемого биоматериала.
10. Активация профмаршрута, включает в себя создание Направлений (объект внутри МИС) для каждого "мероприятия", создание талонов на оплату и оказание услуг для каждого мероприятия с разбивкой по исполнителям.
определение цен и плательщиков для каждой услуги и выставление счетов.
11. МИС закрытая, но позволяет запускать
11.1. Хранимые процедуры с передачей в них параметров или
11.2. Приложение с передачей в него параметров. (МИС это ДАНО, обсуждать, и выдавать гениальные предложения выкинуть такую МИС, нет смысла)
12. Все нужные действия реализованы в Хранимой процедуре, которая делает всё в себе. И так сейчас работает.
13. Минусы процедуры.
13.1. Нет отображения прогресса.
13.2. Нет возможности интерактива с регистратором-оператором.
13.3. Как не крутись, при пиковой загрузке 5-6 регистраторов+15 врачей и лаборантов, и стабильной очереди в 10-20 человек на входе регистратуры, начинают видеть зависания системы из-за блокировок при выполнении "тяжелой процедуры".
14. Написал утилиту на Delphi которая выполняет действия не скопом в одном скрипте, а частями-шагами. Т.е. считывает все необходимые данные, и в цикле по записям-строкам, отдельными запросами вставляет и изменяет данные.
Проблемы 13.1, 13.2, 13.3 полностью решены.
15. Спустя 2 года понадобилось расширить функционал.
16. Решил заодно переписать на Lazarus и прислушаться к советам профессионалов, и не задавать параметры собирая sql запросы текстом, а использовать ParamByName тут и возникли вопросы связанные с NULL которых не может возникнуть при сборке текста запроса без параметров.
Т.к. я дилетанто-школоло то сформулировал вопросы как сумел.

Простите, если Вас обижу, но то, что Вы привели для примера в данном случае показывает - Вам просто нужно количество кода на Паскале увеличить...

Премного вам благодарен, что у вас нет цели меня обидеть. (лайтсарказм).
О да, Главврачи посадят своих лаборантов которые эритроциты считают, посчитать кол-во строк кода, и насыпят мне столько золота , сколько будет строк. Вы таки угадали.
jsa
новенький
 
Сообщения: 68
Зарегистрирован: 28.11.2017 13:46:04

Re: Как передавать null в параметр запроса?

Сообщение Vadim » 08.03.2019 18:30:16

jsa писал(а):Премного вам благодарен, что у вас нет цели меня обидеть. (лайтсарказм).
О да, Главврачи посадят своих лаборантов которые эритроциты считают, посчитать кол-во строк кода, и насыпят мне столько золота , сколько будет строк. Вы таки угадали.

Нда...
Насколько я понял из Вашего сумбурного (и всё-таки обиженного) словоизлияния, у Вас проблемы с временем работы с данными. Делая обработку данных вне БД Вы как раз это время увеличиваете. У Вас есть сервер, который, по умолчанию, имеет намного больше ресурсов, чем любая рабочая станция. Сле5довательно Вы, тем самым, замедляете обработку данных.
jsa писал(а):13.1. Нет отображения прогресса.

Отображение прогресса, в данном (представленном Вами, так что это не я тут всё выдумал ;-) ) случае только добавляет время обработки. Вот смотрите:
- Хранимая процедура:
--- Передача от оператора параметра в процедуру;
--- Выборка данных;
--- Вставка параметра в таблицу вместе с этими данными.
- Внешняя процедура на языке Паскаль:
--- Выборка данных;
--- Передача набора данных и их форматирование на компьютер-клиент;
--- Ввод параметра;
--- Передача вновь сформированного набора данных на сервер;
--- Запись данных в таблицу.
Надеюсь это наглядно?
И постарайтесь не обижаться. Вы знаете про свою задачу всё, мы - только то, о чём Вы нам тут написали. Исходя из Ваших слов, логика программы замедляет обработку данных. Может стоит посмотреть на хранимую процедуру, чем сыпать тут сарказмом, как Вы думаете? ;-)
Vadim
долгожитель
 
Сообщения: 3466
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Как передавать null в параметр запроса?

Сообщение Лекс Айрин » 08.03.2019 18:38:26

jsa, да, чтение исходников иногда целое искусство, особенно, когда они идут на нескольких языках. С непривычки иногда тяжело переключиться с одного на другой. Поищи примеры конкретно для нужного тебе кода. Ну или скачай исходники компонентов alexs-а и используй как шпоры. Наверняка у него есть подходящий вариант.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5307
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Как передавать null в параметр запроса?

Сообщение jsa » 08.03.2019 19:43:14

Vadim писал(а):Делая обработку данных вне БД Вы как раз это время увеличиваете...случае только добавляет время обработки. Вот смотрите:

Это только один из факторов влияющих на время выполнения.
На практике, за счет того, что вместо одного большого скрипта, который блокирует множество таблиц, (про with nolock можно не подсказывать) выполняется множество элементарных маленьких скриптов, не происходит наложение, как привыполнении большой Хранимки запущенной одновременно с нескольких рабочих мест друг на друга.
В итоге всё в сумме работает быстрее.

1 регистратор exe-шник 4-7 сек
1 регистратор Хранимка 3-5 сек
4 регистратора + 10-15 врачей exe-шник 8-10-15 сек на одну активацию
4 регистратора + 10-15 врачей Хранимка сначала работает так же но потом доход до 40 сек на активацию, а может до 1-2 минут. при этом начинает тормозить подвисать и работа врачей.

У Вас есть сервер, который, по умолчанию, имеет намного больше ресурсов, чем любая рабочая станция

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

Нда...
Насколько я понял из Вашего сумбурного (и всё-таки обиженного) словоизлияния....

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

И постарайтесь не обижаться.
Абижяюс-аж-кющать-нимагу.
А можно, если я не буду обижаться, я буду ставить на место светил программирования, которые вместо обсуждения по теме обсуждают изящество кода? :twisted:

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

Смотрели, об оптимизировали вдоль и поперек. Проблема в большом количестве действий и задействованных таблиц, которыми пользуются все работающие в системе постоянно. Ничего кроме разбивки Хранимки на куски и выполнения из внешней программы не сработало.

Добавлено спустя 8 минут 2 секунды:
Лекс Айрин писал(а):Поищи примеры конкретно для нужного тебе кода. Ну или скачай исходники компонентов alexs-а и используй как шпоры. Наверняка у него есть подходящий вариант.

Спасибо, мне не надо. Вопрос то был про передачу параметром значения NULL. И вроде всё обсудили. Можно сворачивать тему.
jsa
новенький
 
Сообщения: 68
Зарегистрирован: 28.11.2017 13:46:04

Пред.След.

Вернуться в Lazarus

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

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

Рейтинг@Mail.ru