• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

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

    Запись на курс до 25 апреля. Получить промодоступ ...

Getallentriesbykey криво ищет по составному ключу

  • Автор темы nvyush
  • Дата начала
N

nvyush

Здравствуйте, все!
Столкнулся с проблемой: есть представление, первый сортированный столбец типа дата, второй сортированный столбец вычисляется по формуле типа @If(SomeField = "SomeValue"; "0"; "1") (пробовал также формулу типа @If(SomeField = "SomeValue"; 0; 1) — без разницы). Выполняю скрипт
Код:
	Redim key(1) As Variant
Set key(0) = dateRange
key(1) = "0"
Set entries = view.GetAllEntriesByKey(key, True)
и получаю нужные записи, выполняю
Код:
	Redim key(1) As Variant
Set key(0) = dateRange
key(1) = "1"
Set entries = view.GetAllEntriesByKey(key, True)
и получаю ноль записей, хотя документы, удовлетворяющие условию поиска точно есть. Более того, меняю формулу столбца на @If(SomeField = "SomeValue"; "1"; "0") и в обоих случаях получаю адекватный результат! Представление перед запуском скриптов индексировал. Кто подскажет, где собака порылась?
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 941
609
BIT
214
без True работает
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 941
609
BIT
214
я имею в виду - что False нужен
 
N

nvyush

я имею в виду - что False нужен
Пробовал и так. Если exactMatch = False или опущен (что, в принципе, одно и то же), то при перестановке значений в формуле столбца "пропадают" противоположные документы. Сейчас попытался переставить столбцы местами, но получил ошибку Invalid key value type. Похоже, придётся отбирать записи только по диапазону дат, а значение второго столбца анализировать "в ручную".
 
H

hosm

nvy как-то пробовала, похожая проблема была из-за того, что дата была мультивальная, закономерности не отследила, переделала вообще без вьюхи. Что-то в хелпе было насчет глючности поиска по составным ключам.
 

VladSh

начинающий
Lotus Team
11.12.2009
1 784
157
BIT
57
По моему, бегать по уже отобранной коллекции, перебирая её - изврат.
Не проще ли собрать формулу для db.Search?
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 941
609
BIT
214
бегать по уже отобранной коллекции,
не всегда..., если это индекс (вьюшки), но (разумеется) луче найти первый элемент и от него бежать по навигатору (если сами доки не нужны)
 

VladSh

начинающий
Lotus Team
11.12.2009
1 784
157
BIT
57
не всегда..., если это индекс (вьюшки), но (разумеется) луче найти первый элемент и от него бежать по навигатору (если сами доки не нужны)
Это само собой :)
Я имел ввиду решение конкретно данной проблемы. "Бежать" может быть много и долго, а Search сразу вернёт нужную коллекцию.
 
D

Darker

Быть может, что дело в том, что ключи должны быть однородными? У вас массив - ассорти из DateRange и String
 
N

nvyush

если сами доки не нужны
Конкретно в данной задаче вся необходимая информация отобрана в entry, сами документы не нужны.
"Бежать" может быть много и долго, а Search сразу вернёт нужную коллекцию
К сожалению, Search не самый быстрый способ получить информацию из БД. К тому же бежать в любом случае придётся — задача собрать из энтрисов отчёт в Ёкселе.
Быть может, что дело в том, что ключи должны быть однородными? У вас массив - ассорти из DateRange и String
Если верить справке, то:
Parameters
keyArray
String (variable-length only), integer, long or double value, or array of string, number, DateTime, or DateRange objects. Each element in the array is compared to a sorted column in the view. The first element in the array is compared to the first sorted column in the view; the second element is compared to the second sorted column; and so on.
"Достоинство — простота, недостаток — не работает" (с)пёрто.
Изменил формулу столбца на @If(SomeField = "SomeValue"; 1; 2), а в код добавил проверку условия:
Код:
	Set entry = entries.GetFirstEntry
Do Until entry Is Nothing
If entry.ColumnValues(1) And typeMask Then Call addReportRow(entry.ColumnValues)
Set entry = entries.GetNextEntry(entry)
Loop
При typeMask = 1 отбираются документы первого типа, при typeMask = 2 — второго, при при typeMask = -1 — все.
 

VladSh

начинающий
Lotus Team
11.12.2009
1 784
157
BIT
57
Конкретно в данной задаче вся необходимая информация отобрана в entry, сами документы не нужны.
Я всего лишь предложил вариант обхода. Чтобы не тра..мучаться с багами лотусни.

К сожалению, Search не самый быстрый способ получить информацию из БД.
На форуме интертраста когда-то давно кто-то выкладывал свои наблюдения... не так всё было и плохо. А если ещё и учесть то, что не придётся ещё раз бежать по докам, то даже не сомневаюсь, что скорость у сёрча не будет меньше.

К тому же бежать в любом случае придётся — задача собрать из энтрисов отчёт в Ёкселе.
В энтрисах я вижу 3 основный достоинства:
- не нужно что-то сортировать;
- получить нужные данные сразу (без второго прохода), с щадящим и равномерным использованием памяти;
- сложные формулы, которые могут быть уже рассчитаны в колонках.
Если какое-то условие не выполняется, то я бы заюзал сёрч, чем использовать энтрисы ради энтрисов..
 
N

nvyush

Чтобы пользователь не очень скучал, вывожу в статус-бар "чч:мм:сс: Отбор документов...", "чч:мм:сс: Экспорт в Excel", "чч:мм:сс: Экспорт завершён". Второе время от первого не отличается ни на секунду, третье от второго — десятки секунд. Так что если что и оптимизировать, то это экспорт, но где у комы педаль газа, я что-то не нашёл.

Да, кстати, Search возвращает коллекцию документов. То есть при переборе коллекции нужно будет открывать документы, а они "весят" существенно больше энтрисов. Конкретно в данном случае документов обоих типов примерно поровну, т.е. энтрисов я перебираю в ~два раза больше, чем нужно, но тяну с сервера ~100 байт/энтрис вместо ~3,5 кбайт/документ.
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 941
609
BIT
214
существенно больше энтрисов
а зачем? я ж описывал метод - получаем первый! энтрис, а далее- анализируем втрой столбец (в цикле), пробегая по нафигатору (ведь второй отсортирован)...
ластэнтрис - тоже есть (со значениями)
есть у нафигатора два интересных св-ва - GotoPos и GetPos
исходя из этих данных - могем методом половинного деления (или другими ;) ) искать "начало" второго ключа
др. словами - быстрее найдем второй ключ не перебирая каждый энтрис (в общем случае)
 
N

nvyush

Имеем представление, сортированное по двум первым столбцам:
Дата |Тип |Нужные значения
-------------------------------------------
01.01.2010|2 |***
02.01.2010|2 |***
03.01.2010|1 |***
03.01.2010|2 |***
04.01.2010|1 |***

Нужно отобрать документы 1-го типа за период с 01.01.2010 по 04.01.2010. Как тут применить метод половинного деления?
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 941
609
BIT
214
я уже выше сказал...
в приведённом куске - не отображена сортировка 2-го в протяжённом диапозоне одной! даты
вот для "таких" случаев
01.01.2010|2 |***
02.01.2010|2 |***
03.01.2010|1 |***
03.01.2010|1 |***
..... 777 раз
03.01.2010|1 |***
03.01.2010|2 |***
.... 555 раз
03.01.2010|2 |***
04.01.2010|1 |***
 
D

Darker

А если не париться и объединить два столбца, поменять формат даты на yyyy/mm/dd, превратить в @text

2010.01.01,2 |***
2010.01.02,2 |***
2010.01.03,1 |***
2010.01.04,2 |***
2010.01.05,1 |***
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 941
609
BIT
214
Darker
тогда получим два неприятных эффекта:
-невозможность обора по диапазону дат
-убиение специфики дат - траблы при различных региональных настройках и таймзонах
 
N

nvyush

Если я правильно понял, то вообще отказаться от Getallentriesbykey, взять навигатор от представления, колонки категоризовать и "прыгать" по категориям? Надо будет устроить "сравнительный забег" на досуге...
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!