| 
    
            
         
         | 
    
    
  | 
v7: Дата в запросе 1С++ VFPOLEDB | ☑ | ||
|---|---|---|---|---|
| 
    0
    
        Master5550    
     29.07.21 
            ✎
    09:11 
 | 
         
        Добрый день. Есть база на 7.7, пытаюсь написать простой запрос к базе через vfp
 
        Соединение=" |Provider=VFPOLEDB.1; |Null = Yes; |Exclusive = No; |SourceType = DBF; |Data Source=" + КаталогИБ() + "; |Mode=ReadWrite; |Extended Properties=""""; |User ID=""""; |Password=""""; |Mask Password=False; |Collating Sequence=MACHINE; |DSN="""""; Попытка OLEDB=СоздатьОбъект("OLEDBData"); Рез=OLEDB.Соединение(Соединение); Исключение сообщить("Нет соединения2!"); КонецПопытки; cmdOLEDB = OLEDB.СоздатьКоманду(); ТекстЗапроса = " |SELECT | Жур.Date, | Жур.IDDoc as [Док $Документ], | Жур.IDDocDef as Док_вид |FROM | 1SJourn as Жур |WHERE // | Жур.Date BETWEEN :НачДата AND :КонДата AND // | Жур.Date >= date('20210701000001') AND | Жур.Date >= '20210701' AND | Жур.IDDocDef = $ВидДокумента.Реализация"; cmdOLEDB.Отладка(1); тз = cmdOLEDB.ВыполнитьИнструкцию(ТекстЗапроса); Ошибка при выполнении запроса: FAILED! ICommandText::Execute(): Operator/operand type mismatch. Как правильно установить отбор по дате в запросе? Я уже всяко пытался  | 
|||
| 
    1
    
        Master5550    
     29.07.21 
            ✎
    09:13 
 | 
         
        База DBF     
         | 
|||
| 
    2
    
        trad    
     29.07.21 
            ✎
    09:13 
 | 
         
        BETWEEN :НачДата~~ AND :КонДата~~     
         | 
|||
| 
    3
    
        dubolom    
     29.07.21 
            ✎
    09:13 
 | 
         
        cast(Left(Жур.DateTimeIddoc, 8) as DateTime)     
         | 
|||
| 
    4
    
        Master5550    
     29.07.21 
            ✎
    09:19 
 | 
         
        (2) Да! Заработало! Спасибо!     
         | 
|||
| 
    5
    
        Master5550    
     29.07.21 
            ✎
    09:35 
 | 
         
        А еще такой запрос не хочет работать
 
        ТекстЗапроса = " |SELECT | Рег.Товар as [Товар $Справочник.Номенклатура], | Рег.КоличествоНачальныйОстаток as КоличествоНачОст, | Рег.КоличествоПриход as КоличествоПриход, | Рег.КоличествоРасход as КоличествоРасход, | Рег.КоличествоКонечныйОстаток as КоличествоКонОст, | Рег.СуммаНачальныйОстаток as СуммаНачОст, | Рег.СуммаПриход as СуммаПриход, | Рег.СуммаРасход as СуммаРасход, | Рег.СуммаКонечныйОстаток as СуммаКонОст, |FROM | $РегистрОстаткиОбороты.ОстаткиТМЦ(:НачДата~~, :КонДата~~,,, | , | (Товар), (Сумма, Количество)) as Рег"; Meta name parser error: недопустимое значение параметра "$РегистрОстаткиОбороты.ОстаткиТМЦ" (2)  | 
|||
| 
    6
    
        Master5550    
     29.07.21 
            ✎
    09:42 
 | 
         
        НачДата = НачМесяца(ТекущаяДата());  
 
        cmdOLEDB.УстановитьТекстовыйПараметр("НачДата", НачДата); cmdOLEDB.УстановитьТекстовыйПараметр("КонДата", КонМесяца(НачДата));  | 
|||
| 
    7
    
        dubolom    
     29.07.21 
            ✎
    09:43 
 | 
         
        (5) Там точно $ нужен перед "РегистрОстаткиОбороты"?     
         | 
|||
| 
    8
    
        Master5550    
     29.07.21 
            ✎
    09:55 
 | 
         
        Переписал запрос 
 
        ТекстЗапроса = " |SELECT | Рег.SP408 as [Номенклатура $Справочник.Номенклатура], | Рег.КоличествоНачальныйОстаток as КоличествоНачОст, | Рег.КоличествоПриход as КоличествоПриход, | Рег.КоличествоРасход as КоличествоРасход, | Рег.КоличествоКонечныйОстаток as КоличествоКонОст |FROM | РегистрОстаткиОбороты.ОстаткиТМЦ(:НачДата~~, :КонДата~~,,, | , | (Номенклатура), (Количество)) as Рег"; Сейчас не могу побороть такую ошибку: FAILED! ICommandText::Execute(): Variable 'НОМЕНКЛАТУРА' is not found.  | 
|||
| 
    9
    
        dubolom    
     29.07.21 
            ✎
    09:59 
 | 
         
        (8) Похоже, надо извращаться с соединением таблиц РегистрОстаткиОбороты.ОстаткиТМЦ и $РегистрОстаткиОбороты.ОстаткиТМЦ.     
         | 
|||
| 
    10
    
        Mikeware    
     29.07.21 
            ✎
    10:55 
 | 
         
        (8) 1.у тебя Товар или Номенклатура?
 
        2.в виртуальной таблице уже не будет никакого SP408, там будет наименование поля  | 
|||
| 
    11
    
        trad    
     29.07.21 
            ✎
    11:09 
 | 
         
        (5) OLEDBCommand не умеет виртуальные таблицы/значения     
         | 
|||
| 
    12
    
        Mikeware    
     29.07.21 
            ✎
    11:12 
 | 
         
        (11) семен семеныч!©     
         | 
|||
| 
    13
    
        trad    
     29.07.21 
            ✎
    11:14 
 | 
         
        (11) + но виртуальные таблицы для DBF таки есть, но это надо призывать dbf-знатаков     
         | 
|||
| 
    14
    
        Mikeware    
     29.07.21 
            ✎
    11:18 
 | 
         
        (13) так вроде в 1с++ почти искаропки работают     
         | 
|||
| 
    15
    
        Arbuz    
     30.07.21 
            ✎
    15:51 
 | 
         
        А чё б не взять 1sqlite? там и cte и оконные...     
         | 
|||
| 
    16
    
        Ёпрст    
     гуру 
    30.07.21 
            ✎
    18:39 
 | 
         
        (15) и работает медленнее, чем правильный запрос на фоксе     
         | 
|||
| 
    17
    
        Ёпрст    
     гуру 
    30.07.21 
            ✎
    18:42 
 | 
         
        На вот, занимайся
 
        https://cloud.mail.ru/public/AeJK/71o1vuzd1  | 
|||
| 
    18
    
        Arbuz    
     09.08.21 
            ✎
    18:05 
 | 
         
        (16) (17) Стало мне скучно и решил я опять посмотреть фокс_vs_1sqlite.
 
        Так как у меня нету галки "быстрая обработка движений" по регистру ОстаткиТМЦ, то я закомментил-разкомментил что надо. Сделал подготовку запросов и выполнить загнал в цикл на 100 итераций. И Чо? Скулайт быстрее фокса в 2,93 раза! Поигрался периодами, количеством итераций - результат - скулайт быстрее до 3 раз на запросе в месяц, на запросе в 3 месяца скулайт быстрее в 1,5-1,2 раза, на запросе в год ситуация обратная фокс быстрее 1,5-1,8 раз. Что характерно при запросе за один день - время сравнительно одинаково, порядка 300 мс на 40к строк результата. Версия сулайта 3,36,0,25. Версия vfpodbc.dll 1,0,2,0.  | 
|||
| 
    19
    
        Ёпрст    
     гуру 
    09.08.21 
            ✎
    18:12 
 | 
         
        (18) там закоментить/расскоментить. При отсутсвии галки или отбора на одном из измерений, будет просто лишний лефт джоин с журналом     
         | 
|||
| 
    20
    
        Ёпрст    
     гуру 
    09.08.21 
            ✎
    18:12 
 | 
         
        (18) ты не верно построил текст запроса на фоксе, не попал в нужный индекс.
 
        Фокс обгоняет скульлайт в разы, так то  | 
|||
| 
    21
    
        Ёпрст    
     гуру 
    09.08.21 
            ✎
    18:13 
 | 
         
        Даже примитивный селект, и тот, на фоксе быстрее     
         | 
|||
| 
    22
    
        Ёпрст    
     гуру 
    09.08.21 
            ✎
    18:28 
 | 
         
        И чего за vfpodbc ? Когда должно быть vfpoledb     
         | 
|||
| 
    23
    
        Ёпрст    
     гуру 
    09.08.21 
            ✎
    18:28 
 | 
         
        9     
         | 
|||
| 
    24
    
        Arbuz    
     10.08.21 
            ✎
    13:56 
 | 
         
        (19) Тут-то вопросов нет, всё так. 
 
        (20) А я его и не строил, взял как есть в (17). (21) Там запрос примитивней некуда. Как там можно не попасть в индекс? (22) Да, верно, я ерунду написал - vfpoledb.dll 9.0.00.5815 Даже не ничего не меняя в (17) у меня скулайт на диапазоне от дня до трёх месяцев быстрее фокса (до 3 раз), а вот уже за год фокс быстрее почти в два раза. Период остатков в базе стоит месяц.  | 
|||
| 
    25
    
        Arbuz    
     10.08.21 
            ✎
    14:21 
 | 
         
        То было на тестовой локальной базе, вот на боевой, база на ссд в сети 100М, активных пользаков нет (я и ещё один):
 
        по текущую дату, число после даты - кол-во строк результата c 01.08.21 12543 1sqlite: 330 фокс: 995 c 01.07.21 12712 1sqlite: 487 фокс: 1141 c 01.06.21 13064 1sqlite: 709 фокс: 1302 c 01.05.21 13192 1sqlite: 778 фокс: 1396 c 01.04.21 13459 1sqlite: 919 фокс: 1522 c 01.03.21 14113 1sqlite: 1050 фокс: 1629 c 01.02.21 14113 1sqlite: 1154 фокс: 1716 c 01.01.21 14128 1sqlite: 1272 фокс: 1802 c 01.12.20 14294 1sqlite: 1437 фокс: 1922 c 01.11.20 14727 1sqlite: 1614 фокс: 2050 c 01.10.20 14849 1sqlite: 1792 фокс: 2182 c 01.09.20 15166 1sqlite: 2010 фокс: 2321 c 01.08.20 15597 1sqlite: 2202 фокс: 2481 c 01.07.20 15720 1sqlite: 2375 фокс: 2673 c 01.06.20 16033 1sqlite: 2601 фокс: 2762 c 01.08.19 17982 1sqlite: 4069 фокс: 3811  | 
|||
| 
    26
    
        Djelf    
     11.08.21 
            ✎
    08:46 
 | 
         
        (25) А вот таких тестов я не делал. Действительно идет линейное замедление чтения у 1sqlite.
 
        Но виноват не 1sqlite, а видимо сама 1С. Потому что, например за год 1sqlite 17927, фокс 7138, но в транзакции 1sqlite 3565, т.е. быстрее фокса. Не понятно почему при блокировках на запись такое происходит, причем и на альтернативном движке от Wirth.  | 
|||
| 
    27
    
        Djelf    
     11.08.21 
            ✎
    11:17 
 | 
         
        +(26) Обманул, в транзакции скорость на этом запросе тоже падает (убрал GROUP BY и посчитал количество записей в секунду). 
 
        Но запрос к журналу не замедляется от количества записей. Видимо дело в конструкции Жур.iddoc = Движения.iddoc, а это уже проблема на стороне 1sqlite и видимо в filtermachine.cpp Поковыряю как будет время...  | 
|||
| 
    28
    
        Ёпрст    
     гуру 
    11.08.21 
            ✎
    14:51 
 | 
         
        (25) Не знаю как ты там меряешь, у меня та этой поделке без изменения текста запроса:
 
        запрос за 1 месяц: 1sqlite: 12383 фокс: 1310 период хранения останков 5 дней.  | 
|||
| 
    29
    
        Ёпрст    
     гуру 
    11.08.21 
            ✎
    14:53 
 | 
         
        И это шляпу со скоростью селекта в скульлайте vs fox еще с Орефковым обсуждали. Тогда пришли к выводу, что это не изменить, и скульлайт всегда в проигрыше.
 
        На счет посмотреть, как у тебя подобрался (если вообще подобрался индекс)Ю смотри ветку на форуме 1cpp Скорее всего, у тебя запрос без участия нужного индекса, отсюда фокс в проигрыше.  | 
|||
| 
    30
    
        Ёпрст    
     гуру 
    11.08.21 
            ✎
    14:54 
 | 
         
        Но, правильный запрос на фоксе рвёт скульлайт как тузик грелку     
         | 
|||
| 
    31
    
        Ёпрст    
     гуру 
    11.08.21 
            ✎
    15:00 
 | 
         
        ЗЫ: запрос за день
 
        1sqlite: 313 фокс: 99 запрос за год  | 
|||
| 
    32
    
        Djelf    
     11.08.21 
            ✎
    15:36 
 | 
         
        (30) В этом я не сомневаюсь. У sqlite есть накладные расходы: преобразование из ascii в uft8 и обратно, и это происходит и при группировке и при сортировке.
 
        Я там менял алгоритм, для УРИБ, т.е. сначала идет быстрое сравнение, но если попали на символ кириллицы - переключаемся к более медленному. Это не сильно влияет. Индекс там правильный, sqlite поменял местами запросы (из-за INNER JOIN). т.е. сначала запрос к Журналу, а потом к Остаткам). Думал что распределение памяти тормозит, но в транзакции все равно есть на этом запросе выигрыш. Подчеркиваю! На этом запросе! В простом запрос к одной таблице фокс на 100% уделает sqlite (нет преобразования кодировок, нет блокировок, возможно чтение не всего блока dbf, а только его части со смещением). Не понимаю, где может быть зарыта собака... Но она где то там ;)  | 
|||
| 
    33
    
        Arbuz    
     11.08.21 
            ✎
    16:17 
 | 
         
        (26) Действительно, как это я упустил возможность выполнять запрос в транзакции. За год получается 1486 против 2202 вне транзакции. Заметно быстрее. 
 
        (28) На самом деле я умолчал о том, что у меня используется пресловутый Witrh'овский движок, причём в клиент-серверном варианте. Скулайт работает через движок 1с, соответственно клиент-серверное кеширование, все дела, а фокс тянет файлы базы через корявый SMB. Может поэтому у меня так. (30) Правильный запрос на фоксе (не примитивный) подразумевает значительные затраты усилий и времени, а на скулайте (особенно новых версий) можно легко и непринуждённо писать сложные запросы. Есть же cte, оконные, математика, регулярки. И сейчас оптимизатор работает почти не требуя вмешательства. И ради удобства и скорости разработки я готов пожертвовать двукратным падением производительности. (27) Очень жаль, что не получилось писать в базу средствами скулайта и работать с внешними dbf'ами. Кстати, Djelf, Wirth'овский движок отслеживает в каком режиме 1с открывает базу, и если не было записи (это документированная фича), то не ставит признак переиндексации при отвале клиента. Так вот - в скулайте с момента появления возможности DELETE база, по видимому, всегда открывается в режиме чтение-запись (может я не прав?). Может это можно как-то регулировать? (ЕМНИП в ранних версия скулайта с DELETE была возможность определять режим окрытия чтения/записи).  | 
|||
| 
    34
    
        Ёпрст    
     гуру 
    11.08.21 
            ✎
    16:26 
 | 
         
        (33) да уж...     
         | 
|||
| 
    35
    
        Ёпрст    
     гуру 
    11.08.21 
            ✎
    16:26 
 | 
         
        ты б ее по сети дбф базу гонял запросами     
         | 
|||
| 
    36
    
        Ёпрст    
     гуру 
    11.08.21 
            ✎
    16:27 
 | 
         
        (32) простейших селект к одной табличке медленнее фокса, проверянно.
 
        Только не надо ставить всякие изделия типа виртовской поделки  | 
|||
| 
    37
    
        Arbuz    
     11.08.21 
            ✎
    16:51 
 | 
         
        (35) не понял 
 
        (36) опять не понял: не надо ставить чтобы скулайт не обгонял фокс и не ломал идиллию?  | 
|||
| 
    38
    
        Ёпрст    
     гуру 
    11.08.21 
            ✎
    17:16 
 | 
         
        (37) при чем тут идилия? У тебя уже не дбф база. Тыб еще на адвантаже пробовал, или на коинбэйсе, а че, тоже дбф     
         | 
|||
| 
    39
    
        Djelf    
     11.08.21 
            ✎
    17:17 
 | 
         
        (33) DELETE работает не так, там просто используется что-то вроде команды 1С Объект.Удалить(1), но на самом деле это не объект, а чуток уровнем ниже RowId_Таблицы.Удалить(1). 
 
        Вот в этом и проблема с UPDATE, для DELETE мне не нужен Объект1С, нужен всего лишь указатель на запись, а для UPDATE нужно получить Объект1С, модифицировать его и только потом записать. Быстрее чем средствами самой 1С, это видимо не получится. А для защиты "от дурака" сделано База.РазрешитьDELETE(0/1). Редко пользуюсь, и только после теста на копии. Не помню чтобы не сработало или сработало не верно, но многолетних тестов не было. А вот "поделику" Wirth, не клиент-серверную, а локальную использую очень-очень давно - никаких проблем не было. 1С`овская их делает больше.  | 
|||
| 
    40
    
        Arbuz    
     11.08.21 
            ✎
    17:29 
 | 
         
        (38) Почему это не дбф? Самый что ни на есть дбф! Доступ только не файловый.     
         | 
|||
| 
    41
    
        Arbuz    
     11.08.21 
            ✎
    17:32 
 | 
         
        (38) А как бы по твоему работал фокс на не дбф базе? ಠ▃ಠ     
         | 
|||
| 
    42
    
        Ёпрст    
     гуру 
    11.08.21 
            ✎
    17:39 
 | 
         
        (40) да да да, а чорный запрос и прямой это тоже запрос     
         | 
|||
| 
    43
    
        Arbuz    
     11.08.21 
            ✎
    17:40 
 | 
         
        (39) т.е. База.РазрешитьDELETE(0/1) не более, чем защита от дурака... Почему-то Wirth считает, что была запись после некоторых скулайтовских запросов, но не всегда. Может я чего не правильно понимаю. Ок. Не велика проблема.
 
        >Быстрее чем средствами самой 1С, это видимо не получится. Жаль Вирт не допилил перевод движка на скулайт.  | 
|||
| 
    44
    
        Arbuz    
     11.08.21 
            ✎
    17:40 
 | 
         
        (42) Не пойму твоей желчи. База строго дбф. Точка.     
         | 
|||
| 
    45
    
        Ёпрст    
     гуру 
    11.08.21 
            ✎
    17:46 
 | 
         
        (44) верь в это.     
         | 
|||
| 
    46
    
        Arbuz    
     11.08.21 
            ✎
    17:48 
 | 
         
        (45) Причём тут вера? Может ты не верно представляешь себе работу этой "поделки"? Структура, файлы, индексы - ничем не отличаются - это та же самая база.     
         | 
|||
| 
    47
    
        Ёпрст    
     гуру 
    11.08.21 
            ✎
    18:01 
 | 
         
        (46) как это работает, я узнал еще 11 лет назад
 
        https://www.1cpp.ru/forum/YaBB.pl?num=1279614832  | 
|||
| 
    48
    
        Arbuz    
     12.08.21 
            ✎
    16:57 
 | 
         
        (47) И что? Погремим регалиями и седовласыми байками? Я тоже участвовал - когда ещё она платная была - тестил и покупал даже. Опять же, и что? Каким образом эти твои доводы в пользу твоего же утверждения, что с Вирт'ом - база уже не дбф? Это не разу не близко ни к адвантейджу, ни к коинбэйзу (я знаю, что это, чьё это и тоже слегка участвовал).
 
        Может снизойдёшь и объяснишь? Может я даже пойму. И не будем уповать на веру. Каким образом хук движка в части доступа и кэширования на уровне страниц файлов вдруг теряет право называться родной дбф базой? Если не брать граничные случаи с превышением объёмов и количеством записей таблиц, то сами файлы базы не отличаются, от слова никак. Если ты думал, что это что-то вроде упомянутых трансляторов, то это не так.  | 
|||
| 
    49
    
        Ёпрст    
     гуру 
    13.08.21 
            ✎
    01:39 
 | 
         
        (48) мне нечего больше сказать чем (28) и (31). А ты и дальше пользуй вирт и прочее.
 
        Да забыл, за год вот так: 1sqlite: 823240 фокс: 36625  | 
 | Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |