Имя: Пароль:
1C
1C 7.7
v7: Ошибка в запросе
0 vsy
 
01.09.21
05:59
Знатоки помогите.
Есть простенький запрос к таблице dbf через fox
ТекстЗапроса="
        |SELECT *
        |FROM KL
        |Where DATA  between "+дата1+" and "+дата2+" AND CH IN (SELECT Val FROM :Спис)  
        |";

                врСписок="";
        Запрос.УложитьСписокОбъектов(сз, врСписок);
        Запрос.УстановитьТекстовыйПараметр("Спис", врСписок);
В отладке ошибка
Where DATA  between {^2021-08-31} and {^2021-09-01} AND CHECK IN (SELECT Val FROM 'bba1b25e-fac6-40d0-95d8-a5b03e23555a')
FAILED! ICommandText::Execute(): Operator/operand type mismatch.
В чем может не совпадение типов, поле CH - числовое, в сз тоже числа.
1 ДенисЧ
 
01.09.21
06:02
В запросе
|Where DATA  between "+дата1+" and "+дата2+" AND CH IN (SELECT Val FROM :Спис)  
в ошибке
Where DATA  between {^2021-08-31} and {^2021-09-01} AND CHECK IN ...

И да
SELECT Val FROM 'bba1b25e-fac6-40d0-95d8-a5b03e23555a'
Это что-то странное. Выбирается какой-то val из строки...
2 Андрей_Андреич
 
naïve
01.09.21
06:04
(1) Это не строка, а таблица, в которую список объектов уложен
3 vsy
 
01.09.21
06:05
Не понял почему это таблица.
4 ДенисЧ
 
01.09.21
06:05
(2)  'bba1b25e-fac6-40d0-95d8-a5b03e23555a' - это строка. Ну как ни крутись, строка...
5 vsy
 
01.09.21
06:07
Согласен (4)
6 Андрей_Андреич
 
naïve
01.09.21
06:09
(4,5) Значит, товарищ неправильно имя таблицы в запросе устанавливает
7 vsy
 
01.09.21
06:12
Как не правильно, оно однозначно, эта единственная таблица, но не из базы 1с
8 Андрей_Андреич
 
naïve
01.09.21
06:18
(7) У ТС
SELECT Val FROM 'bba1b25e-fac6-40d0-95d8-a5b03e23555a'
А как правильно?
SELECT Val FROM bba1b25e-fac6-40d0-95d8-a5b03e23555a
?
9 vladmenleo
 
01.09.21
06:30
(7) не знаю как на фоксе но если через 1с++ делать, то список объектов нужно устанавливать так  Запрос.УложитьСписокОбъектов("Спис", сз);
тут сз я так понимаю список значений с какими-то данными
10 vladmenleo
 
01.09.21
06:33
(7) а в тексте запроса условие соответственно CH IN (SELECT Val FROM #Спис)
11 vladmenleo
 
01.09.21
06:35
(9) Очепятка Запрос.УложитьСписокОбъектов(сз, "#Спис");
12 vsy
 
01.09.21
07:15
(9) Так не проканало
пришлось извратиться так
AND CH IN ("+сзвстроку+")
где сзвстроку списокзначений загнанный в строку.
Не понятно почему не так работает запрос.УложитьСписокОбъектов(сз, врСписок);
13 Андрей_Андреич
 
naïve
01.09.21
07:17
(12) У тебя имя таблицы некошерное
14 vsy
 
01.09.21
07:34
(12)Почему?
15 НоваяВолна
 
01.09.21
07:36
(12) у тебя точно в таблице значения в таблице числовые? Однозначно? А скажем с плавающей запятой... есть?
16 vsy
 
01.09.21
07:39
(15) Все точно без плавающей запятой.
Проблема в bba1b25e-fac6-40d0-95d8-a5b03e23555a, я так понимаю это должна быть строка, по факту нет. Пэтому и Operator/operand type mismatch
17 НоваяВолна
 
01.09.21
07:44
(16) на пустое поле в таблице нарвались, неее? ... отсюда несовпадение типов. А строка она и в Африке строка....
18 vsy
 
01.09.21
07:45
(16) Нет
В предыдущем посте не правильно bba1b25e-fac6-40d0-95d8-a5b03e23555a должна быть таблица из которой выбирать, а по факту строка.
19 Андрей_Андреич
 
naïve
01.09.21
07:49
кавычки в названии таблицы привели к тому что оно воспринимается как строк а не как имя таблицы
20 НоваяВолна
 
01.09.21
07:51
(19) кстати да, похоже... просмотрел
21 vsy
 
01.09.21
07:55
Не понял какие кавычки.
22 Андрей_Андреич
 
naïve
01.09.21
07:55
(19) А эти кавычки добавляет функция
Запрос.УстановитьТекстовыйПараметр("Спис", врСписок);
Не устанавливай параметр, пиши сразу:
AND CH IN (SELECT Val FROM "+врСписок+")
Ну и имена уже придумывай такие, чтобы понятно было
23 vsy
 
01.09.21
08:12
(22)Ругается на врСписок
24 Андрей_Андреич
 
naïve
01.09.21
08:16
(23) Что у тебя врСписок?
25 vsy
 
01.09.21
08:16
врСписок="";
        Запрос.УложитьСписокОбъектов(сз, врСписок);
26 Андрей_Андреич
 
naïve
01.09.21
08:29
(25) Очень странно. Надо задавать непустое значение. Похоже тебя уже клинит (без обид)
27 vsy
 
01.09.21
08:36
врСписок это имя виртуальной таблицы куда укладываютя значения из списказначений (сз)
Поэтому и Запрос.УстановитьТекстовыйПараметр("Спис", врСписок);
28 Mikeware
 
01.09.21
08:39
///********************************
Функция глИмяВременнойТаблицы() Экспорт
    V7SysInfo = СоздатьОбъект("AddIn.V7SysInfo");
    Возврат "[#"+V7SysInfo.СоздатьGUID()+"]";
КонецФункции
29 vladmenleo
 
01.09.21
08:40
(27) Так почему имя этой таблицы пустое? врСписок="";
30 Андрей_Андреич
 
naïve
01.09.21
08:52
(27) Еще раз - нельзя в твоем случае использовать Запрос.УстановитьТекстовыйПараметр
31 Ёпрст
 
01.09.21
09:14
(0)

1.
|Where DATA  between :дата1~~ and :дата2~~
.....
  Запрос.УстановитьТекстовыйПараметр("дата1",ТекущаяДата());
2. в УложитьСписокОбъектов не указываешь тип, в уложенной таблице будут значения "как есть" в таком случае
32 vsy
 
01.09.21
09:41
(31) Не понял где указать тип
33 Ёпрст
 
01.09.21
09:49
(32)В твоём списке сз что лежит ?
34 Salimbek
 
01.09.21
10:12
(33) Да нафиг ему не нужен список. Там лежит одна строка - имя таблицы из которой надо получить данные. Поэтому проще завести переменную ИмяТаблицы = "bba1b25e-fac6-40d0-95d8-a5b03e23555a";
И далее использовать AND CH IN (SELECT Val FROM "+ИмяТаблицы+")

Ну или, в варианте со списком:
(0) AND CH IN (SELECT Val FROM "+врСписок.ПолучитьЗначение(1)+")
35 vsy
 
01.09.21
10:55
(33) В списке находятся числа
(34) Их может быть очень много.
36 Salimbek
 
01.09.21
11:21
(35) "В списке находятся числа" - вранье. "bba1b25e-fac6-40d0-95d8-a5b03e23555a" - это не число.
"Их может быть очень много." - "Их" - это кого? Чисел - ну и пусть. Таблиц - тогда запрос в (0) не будет работать.
37 vsy
 
01.09.21
11:24
В том то и дело bba1b25e-fac6-40d0-95d8-a5b03e23555a должна быть таблицей куда уложен список, а это строка
38 ДенисЧ
 
01.09.21
11:30
Я надеюсь, тут собравшиеся понимают, что
SELECT Val FROM bba1b25e-fac6-40d0-95d8-a5b03e23555a
Это мягко говоря - некорректный синтаксис?
От силы можно предложить
SELECT Val FROM [bba1b25e-fac6-40d0-95d8-a5b03e23555a]
И то зависит от скуля на той стороне...
39 Андрей_Андреич
 
naïve
01.09.21
11:33
(38) В том и дело. Более того - у товарища имя таблицы еще и в кавычках
SELECT Val FROM 'bba1b25e-fac6-40d0-95d8-a5b03e23555a'
40 Salimbek
 
01.09.21
11:34
(37) Это всегда так работает. УложитьСписокОбъектов - он что делает? Создает временную таблицу, куда запихивает твои данные. В ответ тебе, видимо, возвращает Имя таблицы, куда все это запихнулось.
То, что у тебя в ВрСписок - видимо пусто, поэтому программа за тебя создает какой-то файл, куда все это укладывает.
Поэтому если укажешь просто:
Запрос.УложитьСписокОбъектов(сз, "my_tmp_table");
то будет создана временная таблица именно с этим именем. И тогда в запросе сможешь указывать, без всей этой суеты:
ТекстЗапроса="
        |SELECT *
        |FROM KL
        |Where DATA  between "+дата1+" and "+дата2+" AND CH IN (SELECT Val FROM my_tmp_table)  
        |";
41 Salimbek
 
01.09.21
11:37
(38)-(39) - Он использует подключение через OleDB
https://www.1cpp.ru/docum/icpp/html/oledb.html#putobjectlist

УложитьСписокОбъектов / PutObjectList

    Синтаксис: УложитьСписокОбъектов(Объект, ИмяТабл, ВидСпр)

    Параметры:

            Объект - тип: Справочник/Документ/СписокЗначений (содержащий элементы типа Справочник, Документ). Объект, который необходимо уложить во временную таблицу.
            ИмяТабл - тип: Строка. Возвращаемое значение. Имя временной таблицы, которое будет сгенерировано методом и возвращено через этот параметр.
            ВидСпр - тип: Строка. Вид справочника для иерархического включения элементов.

    Описание: сохраняет Объект (или список объектов, если передан список значений) во временную таблицу. Имя временной таблицы генерируется методом и возвращается через второй параметр (именем является GUID). Временная таблица имеет поле VAL CHAR(9) и служебное поле ISFOLDER NUMERIC(1,0).

    Если указан параметр ВидСпр (вид многоуровневого справочника), то таблица будет содержать элементы (без групп), иерархически принадлежащие группам (Подобно оператору "в" встроенного языка запросов 1С).

    Уничтожать временные таблицы явным образом не обязательно ( прим: DROP TABLE MyTmpTbl ) - все временные таблицы будут уничтожены в момент закрытия команды ( Закрыть() ) или при уничтожении объекта OLEDBCommand.

Пример:

ВрТабл = "";
cmd.УложитьСписокОбъектов(ТекГруппа, ВрТабл, "Номенклатура");
Сообщить("Что тут: " + ВрТабл); // Например, "Что тут: 858573b1-5a6f-459e-9c75-ec63e2a1d858"

Короче - я в (40) не прав, тут надо немного по-другому
42 Salimbek
 
01.09.21
11:38
ИмяТаблицы = "";
Запрос.УложитьСписокОбъектов(сз, ИмяТаблицы);

ТекстЗапроса="
        |SELECT *
        |FROM KL
        |Where DATA  between "+дата1+" and "+дата2+" AND CH IN (SELECT Val FROM "+ИмяТаблицы+")";
43 ДенисЧ
 
01.09.21
11:40
(39) На это я указал в самом начале, есличо (с)
44 Андрей_Андреич
 
naïve
01.09.21
11:41
(43) Так вот же - с первых постов ошибка найдена - кавычки из за установитьпараметр
45 Salimbek
 
01.09.21
11:46
(44) Не, ошибка в том, что автор не читал как работает УложитьСписокОбъектов для его типа подключения. И как его правильно использовать.
46 Ёпрст
 
01.09.21
22:45
(35) ок. В (0) исправь только даты, как написал выше, сделай запрос.Отладка(1), текст сюда.
47 vsy
 
05.09.21
04:35
(35) Отладка-
SELECT *
FROM KL
Where DATA  between {^2021-09-01} and {^2021-09-04} and CH IN (SELECT Val FROM '37c5ee4e-6195-48bc-a29c-e10672bbb4ea')
ТЗ=Запрос.ВыполнитьИнструкцию(ТекстЗапроса);
FAILED! ICommandText::Execute(): Operator/operand type mismatch.
48 vladmenleo
 
05.09.21
08:53
(47)
Процедура Сформировать()
    oledb = СоздатьОбъект("OLEDBData");
    oledb.Connect("Provider=VFPOLEDB.1;Deleted=Yes;Data Source=" + КаталогИБ() + ";Mode=ReadWrite;Mask Password=False;Collating Sequence=MACHINE;");
    Команда = oledb.СоздатьКоманду();
    
    ТекстЗапроса1 = "
    |SELECT
    |Номенкл.ID as [Элемент $Справочник.Номенклатура]
    |FROM
    |$Справочник.Номенклатура as Номенкл
    |where
    |    $Номенкл.Артикул = '0-16-1551'
    |";
    
    Тз = Команда.ВыполнитьИнструкцию(ТекстЗапроса1);
    Тз.ВыбратьСтроку();
    // ТекстЗапроса1 - Работает, возвращает строку номенклатуры
    
    
    Сз = СоздатьОбъект("СписокЗначений");
    Сз.ДобавитьЗначение("0-16-1551");
    Сз.ДобавитьЗначение("1-16-2412");
    Сз.ДобавитьЗначение("0-16-1514");
    Сз.ДобавитьЗначение("М1758");
    
    ТекстЗапроса2 = "
    |SELECT
    |Номенкл.ID as [Элемент $Справочник.Номенклатура]
    |FROM
    |$Справочник.Номенклатура as Номенкл
    |where
    |    $Номенкл.Артикул in (Select Val From " + ВрТабл + ")
    |";
    ВрТабл = "";
    Команда.УложитьСписокОбъектов(Сз, ВрТабл);
    Тз = Команда.ВыполнитьИнструкцию(ТекстЗапроса2);
    Тз.ВыбратьСтроку();
    // ТекстЗапроса2 - Работает неверно, возвращает весь справочник номенклатуры
    
    Сз.УдалитьВсе();
    
    СпрНом = СоздатьОбъект("Справочник.Номенклатура");
    СпрНом.НайтиПоКоду("О0009374");
    Сз.ДобавитьЗначение(СпрНом.ТекущийЭлемент());
    СпрНом.НайтиПоКоду("О0009377");
    Сз.ДобавитьЗначение(СпрНом.ТекущийЭлемент());
    СпрНом.НайтиПоКоду("О0009320");
    Сз.ДобавитьЗначение(СпрНом.ТекущийЭлемент());
    СпрНом.НайтиПоКоду("С0001874");
    Сз.ДобавитьЗначение(СпрНом.ТекущийЭлемент());
    
    ТекстЗапроса3 = "
    |SELECT
    |Номенкл.ID as [Элемент $Справочник.Номенклатура]
    |FROM
    |$Справочник.Номенклатура as Номенкл
    |where
    |    Номенкл.ID in (Select Val From " + ВрТабл + ")
    |";
    
    ВрТабл = "";
    Команда.УложитьСписокОбъектов(Сз, ВрТабл);
    Тз = Команда.ВыполнитьИнструкцию(ТекстЗапроса3);
    Тз.ВыбратьСтроку();
    // ТекстЗапроса3 - Работает верно, возвращает отобранные элементы номенклатуры
КонецПроцедуры

А все потому, что кое-кто читать хелп не умеет -
Синтаксис: УложитьСписокОбъектов(Объект, ИмяТабл, ВидСпр)

Параметры:
Объект - тип: Справочник/Документ/СписокЗначений (содержащий элементы типа Справочник, Документ). Объект, который необходимо уложить во временную таблицу.

СписокЗначений (содержащий элементы типа Справочник, Документ) Элементы Карл, а не та срань, что ты туда подсовываешь
49 ДенисЧ
 
05.09.21
09:07
(48) Команда.УложитьСписокОбъектов(Сз, ВрТабл);
А что тут сз, если не ".../СписокЗначений" ?
50 vladmenleo
 
05.09.21
09:24
(49) содержащий элементы типа Справочник, а у него в 0 "в сз тоже числа."
51 Ёпрст
 
05.09.21
11:03
(47) Запрос выполняешь не в монопольном режиме, случаем?
52 Ёпрст
 
05.09.21
11:21
Да. Дату ты неправильно устанавливаешь. В тексте запросва должно быть
{d '2021-09-05'}
53 Ёпрст
 
05.09.21
11:24
А так, списокзначений с числами, уложиться во времянку с пустым значением val.
Метод только для элементов справочника\документов создан. Ибо val - char(9) в нём.
Тут либо insert во времянку, или динамический запрос на in (1,2,4,.....N) лепить. Но можешь встрять на слишком длинном тексте запроса.

Или переписать запрос на sqlite, там список можно с любыми типами укладывать, хоть элементы, хоть строки\числа
54 Ёпрст
 
05.09.21
11:26
55 vsy
 
05.09.21
12:59
(54) Так и получилось слишком длинный запрос. Я его переделал по sqlite вроде работает
56 vsy
 
05.09.21
13:35
Плохо то, что везде используется оледб, а тут еще и sqlite.
57 Ёпрст
 
06.09.21
08:53
(55) каким образом написал запрос на sqllite к сторонней базе ?
58 Ёпрст
 
06.09.21
08:53
кажи код
59 Ёпрст
 
06.09.21
09:00
На счет времянки для оледб, тут готовый код
https://www.1cpp.ru/forum/YaBB.pl?num=1188673318
60 vsy
 
07.09.21
08:04
в (55) не правильно написал. В начале пробовал через sqlite, но ругалась что файл зашифрован че то там еще (потому что база не 1с, использовал базаДанных.Открыть("путь к файлу dbf"). Я в запросе по оле загонял список в строку и CH IN ("+строка+") и вроде работает пока строка не становится слишком большой. Может я не правильно думаю, вообще мне нужен двойной запрос к одной таблице типа
select a1.*,a2.*
from (select * from kl where 'условие') as a1, (select ch from kl where 'условие') as a2
where a1.ch=a2.ch
Короче нужен inner join между запросами. Но конструкция выше тормозит ужасно.
Может у кого есть решение.
(59) спасибо посмотрю, может тут есть решение.