-
Notifications
You must be signed in to change notification settings - Fork 9
sql_select_id
Находит в таблице запись по значениям ключевых полей (их имена заданы в качестве 3-го параметра) или, если таковой не обнаружено, вставляет новую запись. В любом случае возвращает номер заданной записи. Если значение "fake" не задано, оно принимается равным $_REQUEST {sid}.
Основное применение этой процедуры: синхронизация данных.
ВНИМАНИЕ! Текущая реализация предполагает глобальную блокировку таблицы, так что её использование при высокой нагрузке может привести к деградации производительности.
В современных приложениях рекомендуется использовать sql_do_upsert.
Поиск может производиться по нескольким наборам ключевых полей (например, ОГРН, потом ИНН+КПП).
-label => $label, inn => $inn, kpp => $kpp, ogrn => $ogrn, fake => 0, }, ['ogrn'], ['inn', 'kpp']);
Если ни один набор не задан, ведётся поиск по полю label.
В качестве набора полей вместо ссылки на список можно задать ссылку на функцию. В этом случае, если требуемая запись не обнаружена ни по одному предшествующему набору полей и данная функция вернёт ложное значение, то sql_select_id вернёт 0. Смысл такой функции: "условие отсечения", при наступлении которого ни искать, ни добавлять запись не имеет смысла. Типичный пример такого условия: явный отказ пользователя расширять словарь данных.
Найденная запись может отличаться от искомой значением неключевых полей. В связи с этим, помимо поиска как такового, sql_select_id может изменять запись в БД. При этом:
- значения полей, имена которых указаны с лидирующим '-' (например, '-label'), обязательно приводятся в соответствие с аргументом sql_select_id;
- значения прочих полей (например, 'label'), обновляются только в том случае, если в БД у них пустое значение, а соответствующий аргумент непуст.
В списочном контексте и при задании опции {show_diff}, кроме id найденной/созданной записи, возвращает ссылку на хэш с информацией о том, какие операции производились по ходу вызова. Он либо пуст, либо содержит единственную компоненту: еесли запись была создана вновь, то insert:
insert => {... набор полей, как у [[sql_do_insert]] ...},
либо update:
update => {
'поле 1' => [old => 'старое значение 1', new => 'новое значение 1'],
'поле 2' => [old => 'старое значение 2', new => 'новое значение 2'],
...
'поле n' => [old => 'старое значение n', new => 'новое значение n'],
}
sql_select_id ('voc_regions', {
-label => $label,
code => $code,
fake => 0,
}, ['code']); # [[Импорт данных]]
my ($id_user, $result) = sql_select_id ('users', {
-label => 'Foo B. Baz',
login => 'foo',
fake => 0,
}, ['login'], {show_diff => 1});
if ($result -> {update}) {
# надо залогировать изменение...
}
$_REQUEST {_id_org} = sql_select_id (orgs => {
fake => 0,
label => $_REQUEST {_id_org__label}
},
['label'],
sub {[[vb_yes]] ("Организации '$_REQUEST{_id_org__label}' пока нет в справочнике. Добавить её прямо сейчас?")},
) or die '#_id_org#:Действие отменено';