Имя: Пароль:
1C
1C 7.7
v7: 1sqlite виснет при создании таблицы
0 wsxedc83
 
02.01.13
17:36
Имеется следующий код:

база = СоздатьОбъект("SQLiteBase");
база.Открыть(":memory:");
Запрос = база.НовыйЗапрос();
ТекстЗапроса="
|create table journ AS
|SELECT    
|   iddoc,
|   iddocdef
|FROM Журнал
|WHERE (iddocdef = :ВидДокумента.ЗаявкаПокупателя AND Автор = :Автор)
|OR (iddocdef = :ВидДокумента.ПоступлениеТМЦ AND CLOSED = 1)
|OR (iddocdef = :ВидДокумента.Реализация AND ISMARK <>  '*')
|";
Запрос.ВыполнитьЗапрос(ТекстЗапроса);
ТЗ = Запрос.ВыполнитьЗапрос("select * FROM journ");
ТЗ.ВыбратьСтроку();

Виснет. Причем, я пробовал получать в ТЗ то что находится в SELECT в предыдущем запросе - получает 22 тысячи строк, примерно как положено, а вот таблицу на основе этого - не создает.
Если отдельно создать таблицу не заполняя ничем - создает без проблем.
Подскажите пожалуйста что делаю не так? На ошибку в районе ДНК прошу не ссылаться, т.к. на данном этапе неисправима.

Спасибо и с Новым Годом всех!
1 wsxedc83
 
02.01.13
22:48
Апну, может увидит кто...
2 Cthulhu
 
02.01.13
22:53
не над делать create table.
сделай select, прими результат в ТЗ.
если ну пипец как надо этот результат (ТЗ) временно иметь в виде таблицы - уложи эту ТЗ в таблицу.
3 wsxedc83
 
02.01.13
23:11
(2) Делал в виде select, подсовывал в соседний запрос, но в ТЗ, видимо, значения попадают кривые, т.к. запрос по ним ничего не находит:

ТекстЗапроса="
|SELECT    
|  iddoc,
|  iddocdef
|FROM Журнал
|WHERE (iddocdef = :ВидДокумента.ЗаявкаПокупателя AND Автор = :Автор)
|OR (iddocdef = :ВидДокумента.ПоступлениеТМЦ AND CLOSED = 1)
|OR (iddocdef = :ВидДокумента.Реализация AND ISMARK <>  '*')
|";
ТЗн = Запрос.ВыполнитьЗапрос(ТекстЗапроса);
база.УложитьТЗ(ТЗн,"ТабЖурнала");
ТЗ = запрос.ВыполнитьЗапрос("
|select
|  iddocdef
|FROM Журнал
|WHERE iddocdef
|IN (SELECT iddocdef FROM ТабЖурнала) ");
ТЗ.ВыбратьСтроку();
   
В результате - пустая таблица из одного столбца iddocdef
4 aka AMIGO
 
02.01.13
23:12
не пробовал условия по одному добавлять?.. или там убирать..
5 wsxedc83
 
02.01.13
23:19
(4) Да по условиям всё чисто. Даже промежуточная таблица ТЗн нормальная. Даже если выполнить запрос вида select * from ТабЖурнала - отображается куча позиций. Просто они все не совсем похожи на нормальные id, которые выводятся по select * from Журнал
6 КонецЦикла
 
03.01.13
00:10
Стоит посмотреть синтаксис sqllite?
Insert не нужен там?
7 kiruha
 
03.01.13
00:54
А это нормально
ТЗ.ВыбратьСтроку()
на 22 000
8 PZh
 
03.01.13
00:56
(0) А не эта ли строка вызывает зависание?
ТЗ.ВыбратьСтроку()
Для отладки лучше использовать "SELECT top 100".

(3) Временные таблички вряд ли имеет смысл юзать в этом случае, т.к. запрос
... IN (SELECT <что-то> FROM <Временная табличка>) ...
будет скорее всего медленнее чем
... IN (<Полноценный подзапрос (результатом которого была временная табличка в пердыдущем примере>)...

Лучше два раза, три - сколько угодно раз продублировать этот подзапрос где нужно, чем пихать его результат во времянку. Т.к. введение таблички приведет к построению убогого плана запроса (временная табличка то не индексирована).
9 PZh
 
03.01.13
00:59
Т.е. если не в состоянии осознать и объяснить выгоду - делай без временных таблиц.
10 orefkov
 
03.01.13
08:57
(0)
Во-первых, укажи версию 1sqlite
Во-вторых, в данном случае возможно будет лучше вместо "or" в условиях сделать union all по каждому из условий.
(8)
Возможно, в "больших" СУБД это так, но в sqlite все-таки лучше сложить сначала во временную. Потому что иначе он будет выполнять подзапрос везде, где его встретит, а для IN есть оптимизация - через хеш-поиск.
11 wsxedc83
 
03.01.13
17:38
(8) Насчет select top 100 - Спасибо, совет и в самом деле дельный.
По временным таблицам - можно же и индекс сделать, так что не думаю что будет сильно плохо. А у меня как раз ситуация, когда потом этот результат используется несколько раз и чует моё сердце что тратится на этот подзапрос время каждый раз - т.е. как в (10) ситуация описана.
 
(10) Пробовал на 1.0.2.3 и 1.0.2.6
(20) Вариант с UNION ALL прокатил! СПАСИБО, Александр!
12 wsxedc83
 
03.01.13
17:53
Извиняюсь, (11) относилось не к будущему,  а к (10)
AdBlock убивает бесплатный контент. 1Сергей