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

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

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

jsa
постоялец
Сообщения: 295
Зарегистрирован: 28.11.2017 12:46:04

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

Сообщение jsa »

По "рекомендации" в одной из тем стал использовать параметры для передачи в TSQLQuery , вместо того чтобы динамически формировать текст запроса сразу со значениями.
Проблемы возникают с передачей параметров которые могут принимать значение null

Например
var pID : variant;
begin
pID:=null;


... Далее pID может измениться при выполнении других запросов....

Если для передачи параметра в очередной запрос просто написать
ParamByName('pID').AsInteger:= pID;
то в лучае когда pID не меняется ни каким запросом, т.е. он остается null , то возникает ошибка - о невозможности конвертации null в integer

написал так
if pID<>null then ParamByName('pID').AsInteger:= pID;
и работает. Но всё такие любопытно, что не так c null

P.S. про nil некоторые пишут, не работает nil
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

jsa писал(а):Но всё такие любопытно, что не так c null

Это не с NULL "не так", это с логикой программы. ;-)
NULL - это, по идее, не число, не строка, не булево значение. Это полное отсутствие всего и вся. А Вы пытаетесь типу Integer присвоить "неизвестно какой тип", а потом ещё удивляетесь... :-)
Если хотите оставить то, что у Вас есть и при условии, что указанное Вами поле принимает NULL в качестве значения, то можно сделать так:

Код: Выделить всё

ParamByName('pID').AsVariant:= pID; 
Аватара пользователя
alexs
долгожитель
Сообщения: 4069
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь
Контактная информация:

Сообщение alexs »

jsa
Если работаешь с вариантами - не надо преключаться на прямое указание типа. Vadim правильно обозначил.
А вообще, на мой взгляд, использование вариантов - это плохо. В 99.9% случаев это ошибка проектирования ПО.
jsa
постоялец
Сообщения: 295
Зарегистрирован: 28.11.2017 12:46:04

Сообщение jsa »

Vadim писал(а):Это не с NULL "не так", это с логикой программы. ;-)

С логикой программы всё в порядке, не извольте беспокоиться.

NULL - это, по идее, не число, не строка, не булево значение. Это полное отсутствие всего и вся.

таки спасибо, 10 лет работаю с базами данных и всё никак не мог понять, что есть NULL

А Вы пытаетесь типу Integer присвоить "неизвестно какой тип", а потом ещё удивляетесь... :-)

Ага удивляюсь, на ObjectPascal уже n-уже ндцать лет народ пишет программы и костыли для работы с базами данных, а присваивание NULL стандартным типам данных так и не реализовано.
Это помоему во всех языках имеется, но в Pascal своя уникальная философия.
Если хотите оставить то, что у Вас есть и при условии, что указанное Вами поле принимает NULL в качестве значения, то можно сделать так:
ParamByName('pID').AsVariant:= pID;


Уже сделал ParamByName('pID').Value:= pID; Спасибо.

Добавлено спустя 2 минуты 10 секунд:
alexs писал(а):jsa
Если работаешь с вариантами - не надо преключаться на прямое указание типа. Vadim правильно обозначил.
А вообще, на мой взгляд, использование вариантов - это плохо. В 99.9% случаев это ошибка проектирования ПО.

А какие варианты вариантам?
Как можно спроектировать ПО в котором надо работать со значениями полей из базы которые могут принимать значение NULL ?
В T-SQL переменная любого типа может быть IS NULL , но в Pascal как быть с этим?
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

jsa писал(а):таки спасибо, 10 лет работаю с базами данных и всё никак не мог понять, что есть NULL

Пожалуйста! Заходите, если что... ;-)
:-D

Добавлено спустя 1 минуту 22 секунды:
jsa писал(а):В T-SQL переменная любого типа может быть IS NULL , но в Pascal как быть с этим?

А Вас не смущает, что Вы про разные вещи говорите? :-D
Аватара пользователя
Дож
энтузиаст
Сообщения: 900
Зарегистрирован: 12.10.2008 16:14:47

Сообщение Дож »

Вопрос-то какой? NULL -- это значение отдельного типа "null" (единственное возможное значение для этого типа). При попытке передать не число в качестве числа в данном случае приводит к ошибке, а не к неявной конвертации.
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

jsa, для этого можно использовать обычные объекты.
jsa
постоялец
Сообщения: 295
Зарегистрирован: 28.11.2017 12:46:04

Сообщение jsa »

Vadim писал(а):А Вас не смущает, что Вы про разные вещи говорите? :-D

Неа не смущает.
Удивляет больше, почему в языке который так популярен для написания ковырялок в базах данных не реализована нормальная поддержка "неопределенного значения" для всех типов данных.
iskander
энтузиаст
Сообщения: 630
Зарегистрирован: 08.01.2012 18:43:34

Сообщение iskander »

jsa писал(а):Как передавать null в параметр запроса?

Код: Выделить всё

  ParamByName('pID').Value  :=  Null;

Не?
jsa
постоялец
Сообщения: 295
Зарегистрирован: 28.11.2017 12:46:04

Сообщение jsa »

Дож писал(а):Вопрос-то какой?
Вопрос сформулирован в первом сообщении.
NULL -- это значение отдельного типа "null" (единственное возможное значение для этого типа).
что?
null это системная переменная типа variant и НЕ содержит значение.
Т.е. это не полноценная сущность-эрзац пустого значения как во всех СУБД, а нелепый костыль в виде переменной.

Добавлено спустя 1 минуту 28 секунд:
iskander писал(а):Не?

Я так и сделал, о чем написал уже выше.
Вопрос решен.
Просто не все это увидели, и тема начала жить дальше.
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

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

Не удивляйтесь. Паскаль - это последний язык, который придерживается типизации... ;-)
Аватара пользователя
Дож
энтузиаст
Сообщения: 900
Зарегистрирован: 12.10.2008 16:14:47

Сообщение Дож »

что?
null это системная переменная типа variant и НЕ содержит значение.

Статический тип variant предназначен для хранения значений с динамическим типом. null -- это значение динамического типа "null":

Код: Выделить всё

// Из rtl/inc/variant.inc
function Null: Variant;       // Null standard constant
  begin
    VarClearProc(TVarData(Result));
    TVarData(Result).VType := varnull;
  end;


Если записать 5 в Variant, то не будет "5 это системная переменная типа variant и НЕ содержит значение" или какая-то подобная философия, а будет "записано значение 5 типа число".
jsa
постоялец
Сообщения: 295
Зарегистрирован: 28.11.2017 12:46:04

Сообщение jsa »

Дож, я ошибся, NULL не переменная, а функция
Признай тоже свою ошибку "NULL -- это значение отдельного типа "null" (единственное возможное значение для этого типа)."
Null это не тип, как ты тут написал.
И закроем эту нелепую подтему.
Аватара пользователя
alexs
долгожитель
Сообщения: 4069
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь
Контактная информация:

Сообщение alexs »

Если стоит задача очистить значение поля/параметра - то

Код: Выделить всё

DS.ParamByName('pID').Clear
DS.FieldByName('pID').Clear
Аватара пользователя
Дож
энтузиаст
Сообщения: 900
Зарегистрирован: 12.10.2008 16:14:47

Сообщение Дож »

Я настаиваю на том, что есть такой тип, который можно назвать "тип null" или "тип nulltype" или ещё как-то, единственным значением которого является Null.

Я его называю тип null, также он называется и в исходниках fpc:

Код: Выделить всё

const
   varempty = 0;
   varnull = 1;
   varsmallint = 2;
   varinteger = 3;
{$ifndef FPUNONE}
   varsingle = 4;
   vardouble = 5;
   vardate = 7;
{$endif}
   varcurrency = 6;
   varolestr = 8;
   vardispatch = 9;
   varerror = 10;
   varboolean = 11;
   varvariant = 12;
   varunknown = 13;

...

  TVarData(Result).VType := varnull;
Ответить