Имя: Пароль:
1C
 
Вопрос по прямому запросу
0 alexio_alexio
 
25.05.11
13:47
Имеем дбф-версию Торговли 7.7, есть документ "Заявка" с реквизитом "Адрес" (Тип-строка, длина-300). Этот реквиизит забивается через кладр. Нужно найти все раннее введенные заявки, с определенным адресом. Решил подучиться и написать запрос:

База = СоздатьОбъект("OLEDBData");
Рез = База.Соединение("
|Provider=VFPOLEDB.1;
//|Deleted=Yes;
|Null = Yes;
|Exclusive = No;
|SourceType = DBF;
|Data Source=" + КаталогИБ() + ";
|Mode=ReadWrite;
|Extended Properties="""";
|User ID="""";
|Password="""";
|Mask Password=False;
|Collating Sequence=MACHINE;
|DSN=""""");

Запрос = База.СоздатьКоманду();

ТекстЗапроса = "
|SELECT
|Док.IDDoc as Док,
|$Док.Адрес as Адрес
|FROM
|$Документ.Заявка as Док
|WHERE
|$Док.Адрес = :Адрес2";
   
Запрос.УстановитьТекстовыйПараметр("Адрес2", Адрес);
Запрос.Отладка(1);
ТЗ = Запрос.ВыполнитьИнструкцию(ТекстЗапроса);
ТЗ.ВыбратьСтроку();

Здесь "Адрес2" - определенный адрес.

В отладке следующее:

SELECT
   Док.IDDoc as Док,
  Док.sp56980 as Адрес
FROM
   dh56943 as Док
WHERE
   Док.sp56980 = ',428000,Чувашская Республика - Чувашия,,Чебоксары г,,Ильенко Г.А. ул,7,5,23'
ТЗ = Запрос.ВыполнитьИнструкцию(ТекстЗапроса);
{Документ.Заявка.Форма.Модуль(186)}: FAILED! ICommandText::Execute(): Command contains unrecognized phrase/keyword.

1. Не могу понять в чем ошибка?
2. дбф-ка dh56943 содержит поле sp56980, которое в свою очередь содержит только индекс+регион+город (напр.: ,428000,Чувашская Республика - Чувашия,,Чебоксары г, ). А район, улица, д., кв. в других полях sp56981, sp56982... Получается, что условие из запроса
|WHERE
|$Док.Адрес = :Адрес2";
никогда не будет истинным, т.к неполно? Как тут быть?
1 ДенисЧ
 
25.05.11
13:48
В DD что про sp56981, sp56982 написано?
2 Ёпрст
 
гуру
25.05.11
13:51
(0) используй like
3 alexio_alexio
 
25.05.11
14:00
(1) 2 вопрос отпал, sp56980 содержит полный адрес.
4 alexio_alexio
 
25.05.11
14:13
(2) like используется только в ADO или и в 1с++ можно использовать?
5 Попытка1С
 
25.05.11
14:13
(4) Можно.
6 Ёпрст
 
гуру
25.05.11
14:14
(4) ты не поверишь, но везде.
7 alexio_alexio
 
25.05.11
14:19
исправил запрос на:
|WHERE
|$Док.Адрес like :Адрес2";
   
Запрос.УстановитьТекстовыйПараметр("Адрес2", Адрес);

Ошибка та же самая. Подскажите синтаксис с like.
8 Попытка1С
 
25.05.11
14:24
|$Док.Адрес like "+Адрес2+";
9 Попытка1С
 
25.05.11
14:24
это не надо
Запрос.УстановитьТекстовыйПараметр("Адрес2", Адрес);
10 Попытка1С
 
25.05.11
14:25
Т.е. |$Док.Адрес like "+Адрес+";
11 filh
 
25.05.11
14:29
(7) а что в отладке?
12 alexio_alexio
 
25.05.11
14:32
исправил на:
ТекстЗапроса = "
   |SELECT
   |    Док.IDDoc as Док,
   |   $Док.Адрес as Адрес
   |FROM
   |    $Документ.Заявка as Док
   |WHERE
   |    $Док.Адрес like "+Адрес+";
   
   //Запрос.УстановитьТекстовыйПараметр("Адрес2", Адрес);

теперь при открытии документа Заявка ошибка:
|    $Док.Адрес like "+Адрес+";<<?>>
{Документ.Заявка.Форма.Модуль(179)}: Пропущен символ '"' (двойная кавычка)
|    $Док.Адрес like "+Адрес+";<<?>>
{Документ.Заявка.Форма.Модуль(179)}: Пропущен символ ';'
13 antoneus
 
25.05.11
14:32
WHERE
   |    $Док.Адрес like '"+Адрес+"'";
14 Попытка1С
 
25.05.11
14:33
(12) Пля ну ты как маленький
15 filh
 
25.05.11
14:35
ТекстЗапроса = "
   |SELECT
   |    Док.IDDoc as Док,
   |   $Док.Адрес as Адрес
   |FROM
   |    $Документ.Заявка as Док
   |WHERE
   |    $Док.Адрес like "+Адрес;
16 Ёпрст
 
гуру
25.05.11
14:35
(15) не взлетит
17 alexio_alexio
 
25.05.11
14:36
пля, поставил апострафы и кавычки:
|    $Док.Адрес like апостроф кавычка +Адрес+ кавычка апостроф кавычка;

дебаг такой:
SELECT
   Док.IDDoc as Док,
  Док.sp56980 as Адрес
FROM
   dh56943 as Док
WHERE
   Док.sp56980 like ',428000,Чувашская Республика - Чувашия,,Чебоксары г,,Ильенко Г.А. ул,7,5,23                                                                                                                                                                                                                                 '
ТЗ = Запрос.ВыполнитьИнструкцию(ТекстЗапроса);
{Документ.Заявка.Форма.Модуль(187)}: FAILED! ICommandText::Execute(): Command contains unrecognized phrase/keyword.
18 alexio_alexio
 
25.05.11
14:39
как пробелы конечные убрать? хотя я конструкцию '"+Адрес+"'" не понимаю
19 antoneus
 
25.05.11
14:41
WHERE
   |    $Док.Адрес like '"+СокрП(Адрес)+"'";
20 Ёпрст
 
гуру
25.05.11
14:42
так, для начала:

|where like '%'+:Адрес+'%'
|";
Запрос.УстановитьТекстовыйПараметр("Адрес", Адрес);
21 filh
 
25.05.11
14:43
(16) ну, у меня вот такая конструкция работает

SELECT
   Док.IDDoc as Док,
   Док.Адрес as Адрес
FROM
   $Документ.Заявка as Док
WHERE
   Док.Адрес like :Адрес2
22 Попытка1С
 
25.05.11
14:43
WHERE $Док.Адрес like '%"+СокрП(Адрес)+"%'
23 Ёпрст
 
гуру
25.05.11
14:43
+20
|where $Док.Адрес like '%'+:Адрес+'%'
|";
Запрос.УстановитьТекстовыйПараметр("Адрес", Адрес);
24 filh
 
25.05.11
14:43
(20) а, блин, точно
:)
25 alexio_alexio
 
25.05.11
14:47
ТекстЗапроса = "
   |SELECT
   |    Док.IDDoc as Док,
   |   $Док.Адрес as Адрес
   |FROM
   |    $Документ.Заявка as Док
   |WHERE
   |where $Док.Адрес like '%'+:Адрес+'%'
   |";
   
   Запрос.УстановитьТекстовыйПараметр("Адрес", Адрес);

дебаг:
SELECT
   Док.IDDoc as Док,
  Док.sp56980 as Адрес
FROM
   dh56943 as Док
WHERE
where Док.sp56980 like '%'+',428000,Чувашская Республика - Чувашия,,Чебоксары г,,Ильенко Г.А. ул,7,5,23                                                                                                                                                                                                                                 '+'%'
ТЗ = Запрос.ВыполнитьИнструкцию(ТекстЗапроса);
{Документ.Заявка.Форма.Модуль(189)}: FAILED! ICommandText::Execute(): Command contains unrecognized phrase/keyword.
26 filh
 
25.05.11
14:47
(23) А если у него точное соответствие?
27 filh
 
25.05.11
14:48
(25)
ТекстЗапроса = "
   |SELECT
   |    Док.IDDoc as Док,
   |   $Док.Адрес as Адрес
   |FROM
   |    $Документ.Заявка as Док
   |WHERE
   |where $Док.Адрес like '%' :Адрес '%'
   |";
   
   Запрос.УстановитьТекстовыйПараметр("Адрес", СокрЛП(Адрес));
28 ДенисЧ
 
25.05.11
14:48
ТекстЗапроса = "
   |SELECT
   |    Док.IDDoc as Док,
   |   $Док.Адрес as Адрес
   |FROM
   |    $Документ.Заявка as Док
   |WHERE
   |where $Док.Адрес like '%Адрес%'
   |";
   
   Запрос.УстановитьТекстовыйПараметр("Адрес", Адрес);
29 Ёпрст
 
гуру
25.05.11
14:48
(25) ну ёпт.. WHERE лишний убери
30 Ёпрст
 
гуру
25.05.11
14:48
(28) и ты тоже
31 Ёпрст
 
гуру
25.05.11
14:48
(27) и ты..
32 Ёпрст
 
гуру
25.05.11
14:49
:)
33 alexio_alexio
 
25.05.11
14:49
сорри, убрал, но то же самое
34 antoneus
 
25.05.11
14:50
(27) не взлетит
35 filh
 
25.05.11
14:50
(31) ы
:)
36 Попытка1С
 
25.05.11
14:50
Непонимаю нафиг ему параметр устанавливать.
37 Ёпрст
 
гуру
25.05.11
14:50
(33) без условия твой запрос хоть что-то выдаёт ?
38 Ёпрст
 
гуру
25.05.11
14:51
(36) составные запросы зло, в них конструктор не работает.
39 Попытка1С
 
25.05.11
14:53
(38) Конструкторы сами зло.
40 alexio_alexio
 
25.05.11
14:54
(37) без условия ошибка:
SELECT
   Док.IDDoc as Док,
  Док.sp56980 as Адрес
FROM
   dh56943 as Док
ТЗ = Запрос.ВыполнитьИнструкцию(ТекстЗапроса);
{Документ.Заявка.Форма.Модуль(188)}: FAILED! ICommandText::Execute(): Cannot open file c:\временные\тест\1sbdb\dh56943.dbf.
41 filh
 
25.05.11
14:54
ТекстЗапроса = "
|SELECT
|    Док.IDDoc as Док,
|    Док.Адрес as Адрес
|FROM
|    $Документ.Заявка as Док
|WHERE
|    Док.Адрес like '%'+:Адрес+'%'
|";
   
Запрос.УстановитьТекстовыйПараметр("Адрес", Адрес);

вот.
42 Ёпрст
 
гуру
25.05.11
14:54
(39) ну почему, в снеговике, например, текст запроса форматируют.
43 filh
 
25.05.11
14:54
(40) монопольно чтоле делаешь???
44 Ёпрст
 
гуру
25.05.11
14:55
(40) ага, зачЁт.. с этого и надо было начинать.
Поди МонОпОльнО открытой базе запрос выполняешь ?
:))))))))))))))))))))))))
45 1Сергей
 
25.05.11
14:55
(40) внезапно :)
46 filh
 
25.05.11
14:57
+41 тока забыл $ проставить на 2-х строчках...
47 alexio_alexio
 
25.05.11
14:58
(43) да, вери биг сорри=) я учусь пока
48 Ёпрст
 
гуру
25.05.11
14:59
(47) пользуйся решением от hogik - и проблем с монопольной базой не будет.
Ну или пиши запросы на 1sqlite - там и синтаксис попроще и не нужно писать мегаконструкции для попадания в индекс.
Хотя фокс быстрее на некоторых запросах.
49 filh
 
25.05.11
15:00
(47) и еще можешь тренироваться на 1CQA.ert
50 alexio_alexio
 
25.05.11
15:52
Напишите, пожалуйста, правильный вариант на точное соответствие адреса и что обозначают плюсы и % в записи
like '%'+:Адрес+'%'
51 Ёпрст
 
гуру
25.05.11
15:53
52 alexio_alexio
 
25.05.11
15:55
(50) значит + это просто коннект строк
53 Ёпрст
 
гуру
25.05.11
15:56
(52) какой догадливый..
54 alexio_alexio
 
25.05.11
16:02
Итак, остановился на:
ТекстЗапроса = "
   |SELECT
   |    Док.IDDoc as Док,
   |   $Док.Адрес as Адрес
   |FROM
   |    $Документ.Заявка as Док
   |WHERE
   |$Док.Адрес like '%Адрес%'";
   
   //Запрос.УстановитьТекстовыйПараметр("Адрес", Адрес);

Запрос.Отладка(1);
ТЗ = Запрос.ВыполнитьИнструкцию(ТекстЗапроса);
Сообщить(ТЗ.КоличествоСтрок());

debug:
SELECT
   Док.IDDoc as Док,
  Док.sp56980 as Адрес
FROM
   dh56943 as Док
WHERE
Док.sp56980 like '%Адрес%'
0

Выходит, что количество строк равно нулю, хотя заявка с таким адресом есть. Что я не учел?
55 filh
 
25.05.11
16:06
ТекстЗапроса = "
|SELECT
|    Док.IDDoc as Док,
|    $Док.Адрес as Адрес
|FROM
|    $Документ.Заявка as Док
|WHERE
|    $Док.Адрес like '%'+:Адрес+'%'
|";
   
Запрос.УстановитьТекстовыйПараметр("Адрес", СокрЛП(Адрес));

попробуй это
56 alexio_alexio
 
25.05.11
16:14
(55) все равно 0
57 filh
 
25.05.11
16:16
(56) отладку покажи
58 filh
 
25.05.11
16:16
+57 значит нет такого адреса
59 filh
 
25.05.11
16:18
+57 и это, а без условия что то возвращает?
60 alexio_alexio
 
25.05.11
16:18
(57)SELECT
   Док.IDDoc as Док,
  Док.sp56980 as Адрес
FROM
   dh56943 as Док
WHERE
   Док.sp56980 like '%'+',428000,Чувашская Республика - Чувашия,,Чебоксары г,,Ильенко Г.А. ул,7,5,23'+'%'
0
61 alexio_alexio
 
25.05.11
16:19
(59)SELECT
   Док.IDDoc as Док,
  Док.sp56980 as Адрес
FROM
   dh56943 as Док
2173
62 filh
 
25.05.11
16:20
(60)
1. без условия что?
2. условие такое: Запрос.УстановитьТекстовыйПараметр("Адрес", "Республика");
?
63 filh
 
25.05.11
16:21
(61) а, ну значит нет такого адреса там: ",428000,Чувашская Республика - Чувашия,,Чебоксары г,,Ильенко Г.А. ул,7,5,23"
64 alexio_alexio
 
25.05.11
16:23
(61) проведен док с адресом
,428000,Чувашская Республика - Чувашия,,Чебоксары г,,Ильенко Г.А. ул,7,5,23
18.04.11
65 filh
 
25.05.11
16:26
(64) а теперь открой файл dh56943 и посмотри, как хранятся данные.
66 filh
 
25.05.11
16:26
+65 в колонке sp56980
67 alexio_alexio
 
25.05.11
16:37
(66) что интересно там так: ,428032,њєтр°ёър  •хёяєсышър - њєтр°ш ,,њхсюъёрЁ® у,,ђхэшэуЁрфёър  єы,12,,25

мож дело в кодировке, смотрю дбф через прогу "Просмотр DBF"
68 filh
 
25.05.11
16:44
(67) а кодовая страница какая?
69 alexio_alexio
 
25.05.11
16:48
(67) с кодовой страницей разобрался, 1251
70 filh
 
25.05.11
16:50
Запрос.Выполнить("EXECSCRIPT('SET ANSI OFF')");  
   // Устанавливаем время ожидания захвата таблиц , если во время выполнения запроса кто то проводит документы
   // Очень полезная функция - аналогична времени ожидания в 1С
   Запрос.Выполнить("EXECSCRIPT('SET REPROCESS TO 60 SECONDS')");
   // Убираем буфепизацию, чтобы данные возвращаемые запросам всегда были актуальны
   Запрос.Выполнить("EXECSCRIPT('SET REFRESH TO 0,-1')");    
   
   Запрос.Выполнить("Exec('SET TABLEVALIDATE TO 0')");// Отключили блокировки
71 alexio_alexio
 
25.05.11
16:54
(70) база тестовая, так что только я работаю в ней
72 filh
 
25.05.11
16:55
(71) получаешь данные?
73 МастерВопросов
 
25.05.11
16:57
(48) я тоже как то эксперментировал с DBF и у меня прямые запросы работали дольше запросов на языке 1С. А выгрузитьитоги() так, вообще, на порядок быстрее запросов.
ИМХО в семерке запросы имеют смысл только для СКЛ.
74 filh
 
25.05.11
16:58
(73) ой, вот только не надо...
75 Mikeware
 
25.05.11
17:00
(73) "гиви, у тэбя золотие рюки. только вот растют они из жёппы..."©
76 alexio_alexio
 
25.05.11
17:00
(73) Как тогда быстро найти нужные заявки, если
Имеем дбф-версию Торговли 7.7, есть документ "Заявка" с реквизитом "Адрес" (Тип-строка, длина-300). Этот реквиизит забивается через кладр. Нужно найти все раннее введенные заявки, с определенным адресом.
Обычный запрос долго пашет, общий реквизит документа или графа отбора не катят.
77 filh
 
25.05.11
17:02
(76) не слушай его
:)
78 alexio_alexio
 
25.05.11
17:03
(72) не понял, что значит "получаешь данные?"
79 МастерВопросов
 
25.05.11
17:04
(76) так же как и в запросе, но перебором
80 filh
 
25.05.11
17:05
(78) запрос работает? Данные, которые тебе нужны, ты получаешь?
81 alexio_alexio
 
25.05.11
17:06
(80) получаю, что количество строк равно нулю, хотя заявка с таким адресом есть.
82 alexio_alexio
 
25.05.11
17:07
все отбой, завтра со свежей головой еще раз подумаю
83 МастерВопросов
 
25.05.11
17:09
(75) покритикуй:


//    К сожалению, пока виртуальные таблицы в DBF версии вообще не работают. Поэтому запрос приведенный выше придется переписать в развернутый вид
   
ТекстЗапроса = "
|SELECT
|    $Рег.Номенклатура as [Название  $Справочник.Номенклатура] ,
|    $Рег.Фирма as [НаимФирмы  $Справочник.Фирмы],  
|    Цены.Цена as [Цена $Число],
|    $Рег.Количество AS КоличествоОстаток,    
|    $СпрЕдиниц.Штрихкод  AS Штрихкод
|FROM
|    $РегистрИтоги.ОстаткиТМЦ as Рег    
|    LEFT OUTER JOIN
|    $Справочник.Цены as СпрЦен
|     ON
|      $Рег.Номенклатура =  СпрЦен.ParentExt  AND  $СпрЦен.ТипЦен = :ТипЦен
//весь этот гемор(два запроса в запросе) чтобы получить значение периодического реквизита
|     LEFT JOIN (    
|              SELECT
|                Период.objid as objid,
|                  Период.value as Цена
|            FROM 1sconst as Период
|                WHERE
|          Период.date IN
|                            (SELECT
|                              MAX(Константа.date)
|                            FROM 1sconst as Константа
|                            WHERE
|                                (Константа.date <= :ВыбДата ~~)
|                                    AND (Константа.id = $ИсторияРеквизита.Цены.Цена)
|                                   AND (Константа.objid = Период.objid)
|                                )
|        AND Период.id = $ИсторияРеквизита.Цены.Цена
|      ) as Цены ON Цены.objid = СпрЦен.id      
//Конец Гемора с получением периодической цены  
|      LEFT JOIN
|        $Справочник.Единицы as СпрЕдиниц
|      ON
|       $Рег.Номенклатура =  СпрЕдиниц.ParentExt
|WHERE      
|    $Рег.Номенклатура NOT IN (SELECT Val FROM "+ИмяТаблицыНом+")
|     AND
|     $Рег.Фирма IN (SELECT Val FROM "+ИмяТаблицыФирм+")
|     AND
|     $Рег.Склад = :ВыбСклад
|";  

 //РАБОТАЕТ ЭТОТ ПРЯМОЙ ЗАПРОС ЕЩЕ МЕДЛЕНЕЕ ЗАПРОСА НА ВСТРОЕННОМ ЯЗЫКЕ 1С
       
   Запрос. УстановитьТекстовыйПараметр ("ВыбСклад",ВыбСкладНаФорме);
   Запрос. УстановитьТекстовыйПараметр ("ТипЦен",ВыбТипЦен);
   Запрос. УстановитьТекстовыйПараметр ("ВыбДата",ТекущаяДата());
   
Запрос.ВыполнитьИнструкцию(ТекстЗапроса,ТЗ);
84 МастерВопросов
 
25.05.11
17:13
(83) периодич реквизит, наверное, быстрее будет получать через сортировку и select top 1
85 FN
 
25.05.11
17:15
(83) А $ПоследнееЗначение чем не угодило?
86 МастерВопросов
 
25.05.11
17:24
(85) это же DBF-база
87 FN
 
25.05.11
17:31
(86)
А если так:
Текстзапроса="Select TOP 1 VALUE from _1SCONST(NOLOCK)
           |where ID='"+МетаДатаВорк.ИДРеквизитаСправочника("ВидыНалогов","Ставка")+"'
           |and OBJID = ? and
           |DATE<= ? order by DATE DESC, TIME DESC";

Вместо вопросов значения
88 FN
 
25.05.11
17:31
(87)+ имя таблички поправь - это из скульной базы
89 МастерВопросов
 
25.05.11
17:32
цитирую: "Эффективное использование MSSQL при помощи ВК 1С"

в DBF версии в модуле проведения ЗАПРОСЫ НЕ РАБОТАЮТ! Т.к. при этом происходит начало транзакции и драйвер FoxPro не может ничего получить из базы.
Замечание от Uzhast:  На самом деле в модуле проведения запросы работают. Но есть тонкости:...
90 МастерВопросов
 
25.05.11
17:33
(87) см. (84)
91 Конфигурист
 
25.05.11
17:36
Структуру данных адреса, если эта задача постоянная, надо переделывать:
1. могу ввести не по КЛАДРу.
2. КЛАДР - не догма, он меняется со временем.
92 МастерВопросов
 
25.05.11
17:48
Скорость получения остатков по регистру

цитирую:
"я тестировал при выгрузке ~35000 строк
выгрузитьостатки() - 1.7 сек
запрос.Выполнить() + Выгрузить() - 105 сек
...
Давно известный факт - выгрузка итогов быстрее запроса примерно в пять раз."

см. подробности в последнем и предпоследнем посте
93 Ёпрст
 
гуру
25.05.11
17:51
(83,92) нет соединений с использованием индекса

(89) сто лет в обед выполняются запросы в дбф базе в модуле проведения, хоть с фоксом, хоть 1sqlite
94 Ёпрст
 
гуру
25.05.11
17:52
(92) ВыгрузитьИтоги медленнее запроса в ДБФ варианте с правильным использованием индексов в тексте запроса.
95 МастерВопросов
 
25.05.11
17:56
(94) закеж пример!
Оно и в СКЛ пригодится, наверное.
96 Ёпрст
 
гуру
25.05.11
17:58
(95) пример зависит от конкретной базы и от индексов, установленных на табличку итогов и движений регистра
97 Ёпрст
 
гуру
25.05.11
17:59
98 alexio_alexio
 
26.05.11
11:32
(91) а есть идеи?