SQLQuery.InsertSQL и UpdateSQL не видит Params

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

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

tema
постоялец
Сообщения: 376
Зарегистрирован: 24.03.2011 19:19:27

SQLQuery.InsertSQL и UpdateSQL не видит Params

Сообщение tema »

Я вписываю запрос в InsertSQL, в запросе у меня присутствует параметр:

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

insert into sotrudnik
(sfio,soklad,skst,ska,sks,skp,doljnost_iddoljnost)
values
(:sfio,:soklad,:skst,:ska,:sks,:skp,
:iddoljnost
)

iddoljnost - параметр. Но, при добавлении, программа сыпется и ругается, что нет такой колонки iddoljnost...
Может я не так указываю параметр? Я проверял прямо перед инсёртом его можно вывести на экран. Он точно присутствует... :evil:
Причём сам запрос (SQLQuery.SQL) параметр видит! Он же по нему соединяется с другой таблицей!
sts
энтузиаст
Сообщения: 548
Зарегистрирован: 04.04.2008 12:15:44
Откуда: Тольятти

Сообщение sts »

почему не :doljnost_iddoljnost?
wavebvg
постоялец
Сообщения: 355
Зарегистрирован: 28.02.2008 03:57:35

Сообщение wavebvg »

sts писал(а):почему не :doljnost_iddoljnost?


Можно было бы не смущать человека, а сказать, что здесь параметры совпадают с именами полей из запроса.
olegy123
долгожитель
Сообщения: 1643
Зарегистрирован: 25.02.2016 11:10:20

Сообщение olegy123 »

Более расширено скажу когда работает
:doljnost_iddoljnost и :iddoljnost
:iddoljnost - будет правильно если insert в ручную.. если работу по select/insert/update возлагаешь на enginering TSQLQuery, на автоматическую подстановку значений в поля - то внутри него название таблиц и параметров должны совпадать, иначе нужно хранить таблицу согласований этих полей..
если требуется заменить с :doljnost_iddoljnost с :iddoljnost, то проще указать в Select-e синоним поля select doljnost_iddoljnost as iddoljnost .. и использовать везде.

wavebvg писал(а):Можно было бы не смущать человека, а сказать, что здесь параметры совпадают с именами полей из запроса.

insert запрос написан правильно.
tema
постоялец
Сообщения: 376
Зарегистрирован: 24.03.2011 19:19:27

Сообщение tema »

Может я неправильно выразился... Я просто в заголовке это написал.
Уточню:
SQLQuery есть такая штука, которая называется Params. Туда можно занести параметры. И в запросе SQLQuery.SQL вызвать их через двоеточие.
Например, в Params хранится параметр par1, тогда в SQLQuery.SQL можно написать так:

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

select * from mytable where id=:par1;

И это будет работать. Так же как работает мой SQLQuery.SQL сейчас:

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

select * from sotrudnik where
doljnost_iddoljnost=:iddoljnost

iddoljnost - это параметр, который хранится в Params и служит для связки двух таблиц. В SQLQuery.SQL всё работает и при замене значения параметра изменяется выдача по запросу. А вот SQLQuery.InsertSQL и SQLQuery.UpdateSQL упорно не видят этого параметра и ругаются, что у меня нет колонки с именем iddoljnost
olegy123
долгожитель
Сообщения: 1643
Зарегистрирован: 25.02.2016 11:10:20

Сообщение olegy123 »

При SQLQuery.Insert() / SQLQuery.Edit() / SQLQuery.Post() ?
Тогда все правильно, что не видит...

Такой запрос без ошибок выполнится только при SQLQuery.ExecSQL.

Добавлено спустя 9 часов 25 минут 17 секунд:
В Delphi изначально были TQuery и TTable.. TQuery могло только SQL- ить, а TTable - обладала табличным функционалом (append/insert/edit/delete)..
В Lazarus-е SQLQuery обладает двойственными способностями:
TQuery - SQLQuery.SQL/SQLQuery.ExecSQL данные берутся из списка Params.
TTable - SQLQuery.InsertSQL/SQLQuery.UpdateSQL - данные и название полей берутся из списка Fields
tema
постоялец
Сообщения: 376
Зарегистрирован: 24.03.2011 19:19:27

Сообщение tema »

Очень грустно и негибко выходит :(
Как же мне задать параметры для SQLQuery.InsertSQL/SQLQuery.UpdateSQL ? Сейчас это жуткий костыль в виде указания числа напрямую в тексте SQL, повешенный на событие SQLQuery2AfterScroll, поэтому я его и вынес отдельной строкой, чтобы:

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

procedure TForm1.SQLQuery2AfterScroll(DataSet: TDataSet);
begin
  SQLQuery3.Active:=false;
  SQLQuery3.InsertSQL.Strings[4]:=SQLQuery2.FieldByName('iddoljnost').AsString;
  SQLQuery3.Active:=true;
end;
Аватара пользователя
Снег Север
долгожитель
Сообщения: 3071
Зарегистрирован: 27.11.2007 15:14:47
Контактная информация:

Сообщение Снег Север »

Ну я вот, например, InsertSQL и UpdateSQL вообще никогда не пользуюсь. Составляю запросы в коде и выполняю через ExecSQL.
olegy123
долгожитель
Сообщения: 1643
Зарегистрирован: 25.02.2016 11:10:20

Сообщение olegy123 »

Снег Север писал(а):Ну я вот, например, InsertSQL и UpdateSQL вообще никогда не пользуюсь. Составляю запросы в коде и выполняю через ExecSQL.

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

tema писал(а):Очень грустно и негибко выходит

Это очень гибкий подход. Этот опыт наработанный более 20 лет.

tema писал(а):Сейчас это жуткий костыль в виде указания числа напрямую в тексте SQL, повешенный на событие SQLQuery2AfterScroll, поэтому я его и вынес отдельной строкой, чтобы:

Вешать на OnAfterScroll - работу с другими БД - это жеский Хак. И как правило неправильный..

tema писал(а):SQLQuery3.InsertSQL.Strings[4]:=SQLQuery2.FieldByName('iddoljnost').AsString;

Зачем это нужно?

Добавлено спустя 18 минут 54 секунды:
tema писал(а):iddoljnost - это параметр, который хранится в Params и служит для связки двух таблиц.

Если тебе нужно связать две таблицы то не обязательно их связывать в ручную через Params.
в SQLQuery есть DataSource в который нужно указать DataSet первичной таблицы, и в SQL указать на ":первичный ключ"
tema
постоялец
Сообщения: 376
Зарегистрирован: 24.03.2011 19:19:27

Сообщение tema »

olegy123 писал(а):
tema писал(а):iddoljnost - это параметр, который хранится в Params и служит для связки двух таблиц.

Если тебе нужно связать две таблицы то не обязательно их связывать в ручную через Params.
в SQLQuery есть DataSource в который нужно указать DataSet первичной таблицы, и в SQL указать на ":первичный ключ"

Я именно так и делаю. И, когда так делаешь, в Params автоматически появляется параметр ":первичный ключ", который и используется в SQL. Но вот хотелось бы, чтобы этот параметр видел и InsertSQL и UpdateSQL.
А как Вы думали связывается всё, после указания DataSet первичной таблицы? Откуда он берёт этот ":первичный ключ" по-вашему? Из Params и берёт, предварительно создав его там.
olegy123 писал(а):
tema писал(а):Сейчас это жуткий костыль в виде указания числа напрямую в тексте SQL, повешенный на событие SQLQuery2AfterScroll, поэтому я его и вынес отдельной строкой, чтобы:

Вешать на OnAfterScroll - работу с другими БД - это жеский Хак. И как правило неправильный..

С удовольствием выслушаю как сделать правильно! Для этого я и создал данную тему
olegy123 писал(а):
tema писал(а):SQLQuery3.InsertSQL.Strings[4]:=SQLQuery2.FieldByName('iddoljnost').AsString;

Зачем это нужно?

В каком смысле "зачем"? Я же вначале темы написал зачем. Затем, чтобы сделать insert с определённым doljnost_iddoljnost. Приходится это значение вставлять прямо в SQL вручную, что я и делаю: ставлю в 4ю строчку запроса число, которое беру из другого запроса SQLQuery2.FieldByName('iddoljnost').AsString
olegy123
долгожитель
Сообщения: 1643
Зарегистрирован: 25.02.2016 11:10:20

Сообщение olegy123 »

При выполнении SQL запроса
tema писал(а):select * from sotrudnik where
doljnost_iddoljnost=:iddoljnost

Все поля doljnost_iddoljnost будут иметь тоже значение что и iddoljnost

Если нужно внести новые данные в зависимую таблицу то тогда есть такое событие OnAfterInsert() где можно записать так SQLQuery3.FieldByName('doljnost_iddoljnost').AsInteger:=SQLQuery2.FieldByName('iddoljnost').AsInteger;
- смысл простой, если во вторичную таблицу SQLQuery3 вводится новые данные, то некоторые можно уже внести сразу.
tema
постоялец
Сообщения: 376
Зарегистрирован: 24.03.2011 19:19:27

Сообщение tema »

Кстати, точно! Можно же так! Это лучше, чем AfterScroll. Спасибо! :D
Аватара пользователя
Снег Север
долгожитель
Сообщения: 3071
Зарегистрирован: 27.11.2007 15:14:47
Контактная информация:

Сообщение Снег Север »

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

Сообщение alexs »

Снег Север писал(а):Эти SQL бесполезны совершенно, если в SELECT стоит что-то чуть сложнее тупого перечисления всех полей. А у меня это - типичная ситуация. И тут уже кто-то напарывался на подобное, чуть изменив SQL. Поэтому хорошим стилем будет отказываться от этой лабуды сразу.

Не правда ваша
Как раз INSERT/UPDATE/DELETE SQL дают большие возможности. Если у тебя по логике идёт изменение записей в нескольких таблица - достаточно твои запросы обернуть в процедуру и вызвать уже процедуру.
А писать код на стороне клиента не нужно.
Да и атомарность операций повышается. Проще управлять транзакциями.
Аватара пользователя
Снег Север
долгожитель
Сообщения: 3071
Зарегистрирован: 27.11.2007 15:14:47
Контактная информация:

Сообщение Снег Север »

alexs писал(а):Если у тебя по логике идёт изменение записей в нескольких таблица - достаточно твои запросы обернуть в процедуру и вызвать уже процедуру.
А писать код на стороне клиента не нужно.
Да и атомарность операций повышается. Проще управлять транзакциями.
В некоторых случаях процедуры полезны, в некоторых - бесполезны. Транзакции мне вообще неинтересны, у меня основной средой является mysql myisam, где понятие транзакции отсутствует. Так что то, что вы понимаете под транзакцией - только в паскалевском коде. И основные базы должны, по условиям работы, допускать перенос через копирования файлов, что с наличием процедур не совместимо.
Ответить