Имя: Пароль:
1C
1C 7.7
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
Независимо от того, куда вы едете — это в гору и против ветра!