powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Не находится запись, которая точно есть в БД
4 сообщений из 4, страница 1 из 1
Не находится запись, которая точно есть в БД
    #40105104
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Столкнулся со странной проблемой.

Есть самописный скрипт-демон, который обеспечивает синхронизацию данных между разными ИС.
В контексте моей проблемы алгоритм следующий:

1. При первом запуске скрипт считывает из БД перечень оборудования:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
SELECT ip.USERCODE AS `id`
, inet_ntoa(ip.USERIP) AS `ip`
, ip.MAC AS `mac`
, sw.DATEADD AS `date`
, sw.NAZV AS `title`
, sw.LOCATION AS `location`
, rd.SN AS `serial`
, rd.INV AS `inventory`
, rd.SHTRIH AS `barcode`
, rt.TOVARNAZV AS `model`
, 0+rp.CODENUMBER AS `parent#`
, rp.OPIS AS `info`
, rp.LOCATION AS `area`
, 0+ra.CODE AS `address#`
, ra.KLUCH AS `keyinfo`
, ra.WORKDOP AS `workinfo`
, ra.DOP AS `notes`
FROM `tbl_ip` ip
JOIN `tbl_switch` sw ON (sw.CODE = ip.USERCODE)
JOIN `tbl_tovar` rd ON (rd.CODE = sw.SKLADCODE)
JOIN `tbl_tovartype` rt ON (rt.CODE = rd.TOVARCODE)
JOIN `tbl_uzel` rp ON (rp.CODE = sw.UZELCODE)
JOIN `tbl_house` ra ON (ra.CODE = rp.HOUSECODE)
WHERE ip.TYPER = 3 AND ip.USERIP > 0 AND sw.DEVTYPER = 3
ORDER BY ip.USERIP


Результат хранится в ассоциированном массиве (в кеше):
Код: php
1.
2.
3.
4.
5.
6.
7.
	$dict['SWITCH'] = [];
	$res = $us->query('switch_list');
	foreach ($res as $row)
	{
		$row['_CLOCK'] = time();
		$dict['SWITCH'][$row['ip']] = $row;
	}


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

2. Затем в процессе работы скрипт получает информацию об оборудовании по его IP-адресу:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
if (isset($rec['NODE'])) $rec['NODE'] = trim($rec['NODE']);
if ($rec['NODE'])
{
	if (array_key_exists($rec['NODE'], $dict['SWITCH']) && ((time() - $dict['SWITCH'][$rec['NODE']]['_CLOCK']) < 3600)) {
		$tmp = $dict['SWITCH'][$rec['NODE']];
	} else {
		$param = [':ip'=>$rec['NODE']];
		$tmp = $us->query('switch_find', $param);
		if ($tmp) {
			$tmp = $tmp[0]; 
			$tmp['_CLOCK'] = time();
			$dict['SWITCH'][$tmp['ip']] = $tmp;
		} else  {
			if (array_key_exists($rec['NODE'], $dict['SWITCH'])) unset($dict['SWITCH'][$rec['NODE']]);
		}
	}
	if ($tmp) {
		$rec['LOCATION'] = $tmp['location'];
		if ($tmp['keyinfo'] || $tmp['workinfo']) $rec['WORKINFO'] = $tmp['keyinfo'].' / '.$tmp['workinfo'];
	} else {
		$rec['LOCATION'] = "! [{$rec['NODE']}] не найден в UserSide";
	}
}



Устройство ищется в кеше, если оно найдено и срок действия кеша не истек, то используются данные из кеша.
В ином случае устройство ищется в БД:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
SELECT ip.USERCODE AS `id`
, inet_ntoa(ip.USERIP) AS `ip`
, ip.MAC AS `mac`
, sw.DATEADD AS `date`
, sw.NAZV AS `title`
, sw.LOCATION AS `location`
, rd.SN AS `serial`
, rd.INV AS `inventory`
, rd.SHTRIH AS `barcode`
, rt.TOVARNAZV AS `model`
, 0+rp.CODENUMBER AS `parent#`
, rp.OPIS AS `info`
, rp.LOCATION AS `area`
, 0+ra.CODE AS `address#`
, ra.KLUCH AS `keyinfo`
, ra.WORKDOP AS `workinfo`
, ra.DOP AS `notes`
FROM `tbl_ip` ip
JOIN `tbl_switch` sw ON (sw.CODE = ip.USERCODE)
JOIN `tbl_tovar` rd ON (rd.CODE = sw.SKLADCODE)
JOIN `tbl_tovartype` rt ON (rt.CODE = rd.TOVARCODE)
JOIN `tbl_uzel` rp ON (rp.CODE = sw.UZELCODE)
JOIN `tbl_house` ra ON (ra.CODE = rp.HOUSECODE)
WHERE ip.TYPER = 3 AND ip.USERIP > 0 AND sw.DEVTYPER = 3
AND ip.USERIP = inet_aton( :ip )



Если находится — добавляется в кеш с новой временной отметкой.
Если не находится, то выдает соответствующую ошибку.

Проблема в том, что устройство никогда не находится, в $tmp возвращается пустой набор данных.
Хотя если выполнить этот же запрос с таким же входным параметром, то устройство находится.

Не могу понять, почему так происходит.

Код $us->query довольно громоздкий, но в нем происходит создание ресурса, загрузка из него данных и освобождение (закрытие) ресурса.
...
Рейтинг: 0 / 0
Не находится запись, которая точно есть в БД
    #40105123
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.
что устройство никогда не находится, ...
Хотя если выполнить этот же запрос с таким же входным параметром, то устройство находится.

Наиболее вероятно, что входной параметр при программном и ручном выполнении ни разу не "такой же". А глаз замылился и не видит какой-то мелочи.

Попробуй сделать вот так:
Код: sql
1.
... AND ip.USERIP = ( @tmp_ip := inet_aton( :ip ) )


и сразу по выполнении запроса, пусть и с пустым результатом, посмотреть, что вернёт
Код: sql
1.
SELECT @tmp_ip, INET_NTOA(@tmp_ip)
...
Рейтинг: 0 / 0
Не находится запись, которая точно есть в БД
    #40105125
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina
Наиболее вероятно, что входной параметр при программном и ручном выполнении ни разу не "такой же"

Да нет, я добавлял в отладочный вывод текст SQL-запроса и значения параметров и проверял именно с ними.

Akina
Попробуй сделать вот так:

Спасибо, попробую.
А что это должно дать?
Сделать прямо в теле скрипта?
...
Рейтинг: 0 / 0
Не находится запись, которая точно есть в БД
    #40105130
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.
А что это должно дать?

Это запишет переданный критерий в переменную, и ты на неё попристальнее сможешь посмотреть. Именно в выполняемом запросе, не "я собираюсь подставить", а "я подставил". Впрочем, то же можно и в General Log глянуть.
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Не находится запись, которая точно есть в БД
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]