Имя: Пароль:
1C
1С v8
Отправка "сложных" запрос к Oracle через ADODB
0 1S_User
 
19.09.16
12:00
Дано.
База Oracle, к которой работают прямые "односложные" запросы типа "Выбрать поле из таблица Где ДругоеПоле = '123'"

Надо.
Заставить выполнять не односложные запросы.
Хотя бы
:v := '123';
select поле из таблица where ДругоеПоле = :v

Сразу отвал. Вообще даже при попытке дважды выполнить работающий select
select поле из таблица where ДругоеПоле = '123';
select поле из таблица where ДругоеПоле = '124';
тоже отвал "invalid character". Такое ощущение, что любой запрос воспринимает, как одну строку.
Что-то с этим можно сделать (отказ от ADODB невозможен, через него написано уже все). Да, в виде вот таких односложных запросов. )
1 Fragster
 
гуру
19.09.16
12:06
с каких пор адодб научился пакетные запросы слать?
2 DrZombi
 
гуру
19.09.16
12:07
(0) Зачем тебе сразу несколько запросов?
Ты как представляешь себе считывать данные?
3 1S_User
 
19.09.16
12:09
(2) Конкретно поступило требование все переписать на связанные подготовленные выражения с использованием связанных переменных (хз, для чего, может, увидели угрозу безопасности или считают, что будет оптимальнее). А чтобы это сделать, надо сначала подготовить выражение, а потом его выполнить.
4 DrZombi
 
гуру
19.09.16
12:09
(0) Можно просто писать так:

Выбрать Запрос № 1
Поле 1 Как Номер запроса

Объединить Все

Выбрать Запрос № 2
Поле 2 Как Номер запроса

...

т.д.
через объединить получаешь Огромную простыню, с результатами... Затем обрабатываешь её :)
5 1S_User
 
19.09.16
12:09
(1) Вот и я так понял, что он не научился...
А есть где-нибудь инфа по этому поводу?
6 1S_User
 
19.09.16
12:10
(4) Это само собой. Цель не в этом. Цель - подготовленное выражение и его использование... И я так понимаю, при использовании ADODB этого не сделать.
7 1S_User
 
19.09.16
12:11
https://habrahabr.ru/post/148446/
Короче, вот по такому принципу надо переписать все селекты. )
8 DrZombi
 
гуру
19.09.16
12:15
(6) Что значит Подготовленное?

Зачем в 1С вообще переменные?
типо :v := '123';


(7) Зачем? И Глупо :)


ADO и параметры
https://support.microsoft.com/ru-ru/kb/181734
9 DrZombi
 
гуру
19.09.16
12:15
В общем у АДО есть параметры
10 1S_User
 
19.09.16
12:16
(8) Видимо, потому, что те, кому отсылаются подобные запросы, считают, что это не безопасно. Мне не уточняли. Надо и все. :)
11 Fragster
 
гуру
19.09.16
12:16
(6) сделать
12 1S_User
 
19.09.16
12:16
(11) Как?
13 Fragster
 
гуру
19.09.16
12:18
(12)
Функция СоздатьКомандуАДО(Соединение, Текст)
    Команда = Новый ComОбъект("ADODB.Command");
    Команда.ActiveConnection = Соединение;
    
    Команда.CommandType = мМагияСКЛ.adCmdText;
    Команда.Prepared = Истина;
    
    Команда.CommandText = Текст;
    Возврат Команда;
КонецФункции
14 Fragster
 
гуру
19.09.16
12:18
Функция ВыполнитьКомандуАДО(Команда)
    
    Попытка
        Результат = Команда.Execute();
    Исключение
        Инфо = ИнформацияОбОшибке();
        ВызватьИсключение "Ошибка выполнения команды!" + Символы.ПС + Команда.CommandText + Символы.Пс + ПредставлениеОшибки(Инфо);
    КонецПопытки;
    
    Возврат Результат;
КонецФункции
15 Fragster
 
гуру
19.09.16
12:18
Команда = СоздатьКомандуАДО(Соединение,
        "INSERT INTO FSInventBarcode1C
        |    (DocumentType, RecordId, Status, ItemId, ItemBarCode)
        |VALUES
        |    (1, ?, 2, ?, ?)");
    
    Выборка = Результат.Выбрать();
    ТекНомер = ПолучитьОбновитьПоследнийНомерDAX(Выборка.Количество(), мСоответствиеОбъектовДляОбмена.ИмяТипаПриемника_Штрихкоды1с);
    
    Счетчик = ПолучитьСтруктуруСчетчика(Выборка.Количество(), "Выгрузка штрихкодов");
    Пока Выборка.Следующий() Цикл
        
        ОбновитьСостояниеСчетчика(Счетчик);
        Команда.Parameters.Item(0).Value = ОтформатироватьИОбновитьСчетчикDAX(ТекНомер);
        Команда.Parameters.Item(1).Value = Выборка.СсылкаВДругойИБ;
        Команда.Parameters.Item(2).Value = Выборка.Штрихкод;
        
        ВыполнитьКомандуАДО(Команда);

        Набор = РегистрыСведений.Штрихкоды.СоздатьНаборЗаписей();
        Набор.Отбор.Код.Установить(Выборка.Код);
        ПланыОбмена.УдалитьРегистрациюИзменений(мСоответствиеОбъектовДляОбмена.УзелОбмена, Набор);
    КонецЦикла;
16 DrZombi
 
гуру
19.09.16
12:18
(12) Забей просто, очень безопасно. Аж описаться...
Используй параметры, куда безопасней :)

select поле из таблица where ДругоеПоле = "123"
17 DrZombi
 
гуру
19.09.16
12:19
(15) Вот я ему и привел в (8) такое, только на С++ :)
18 DrZombi
 
гуру
19.09.16
12:19
+ Его не устроило :)
19 Fragster
 
гуру
19.09.16
12:20
еще пытался ускорить через асинхронное выполнение, но оно немного глючило на разных драйверах
20 Fragster
 
гуру
19.09.16
12:20
особенно если больше одного запроса одновременно слать
21 Fragster
 
гуру
19.09.16
12:22
вот как-то так:
Процедура УстановитьСтатус(Команда, RECORDID, Статус)
    
    Параметры = Новый COMSafeArray("VT_VARIANT", 3);
    Параметры.SetValue(0, Статус);
    Параметры.SetValue(1, ТекущаяДата());
    Параметры.SetValue(2, СокрЛП(RECORDID));
    
    Попытка
        Пока
            Команда.state = мМагияСКЛ.adStateExecuting
        Цикл
            // ждем
        КонецЦикла;
        Команда.Execute(, Параметры, мМагияСКЛ.adAsyncExecute + мМагияСКЛ.adExecuteNoRecords);
    Исключение // если слишком много асинхронных вызовов, то надо дать просраться
        Попытка
            Команда.Execute(, Параметры, мМагияСКЛ.adExecuteNoRecords);
            ДобавитьСообщение("Синхронное обновление таблицы обмена!", СтатусСообщения.Информация);
        Исключение
            Инфо = ИнформацияОбОшибке();
            лТекстСообщения = "обновления таблицы обмена для строки " + RECORDID + " : " + ПредставлениеОшибки(Инфо);
            лСтатусСообщения = СтатусСообщения.Важное;
            ДобавитьСообщение(лТекстСообщения, лСтатусСообщения);
            //ВызватьИсключение "Ошибка обновления таблицы обмена для строки " + RECORDID + "!";
        КонецПопытки
    КонецПопытки
КонецПроцедуры
22 1S_User
 
19.09.16
12:23
Спасибо, буду пробовать.
23 1S_User
 
19.09.16
12:31
Ну, получается, если мы так программно сначала подготавливаем команду, потом вызываем, это будет 2 запроса: 1 на подготовку, другой на использование с параметрами, вместо одного непараметрического?
Убойная оптимизация.
За один запрос, получается, сделать нереально?
24 Fragster
 
гуру
19.09.16
12:33
(23) 1. безопасность (не трахнуть через sql injection, в случае с 1с - это может сышграть при передаче строк, или строковых представлений чисел >1000 (стандартный выстрел в ногу)).
2. небольшое ускорение - для использования в цикле, как у меня.
25 spock
 
19.09.16
12:34
26 Fragster
 
гуру
19.09.16
12:34
(25) это про хранимки статья
27 spock
 
19.09.16
12:42
(23) те, кому запрос уходит, хотят оптимизации построения плана запроса.
28 spock
 
19.09.16
12:44
(26) пример про ХП, а применение любое.
29 Fragster
 
гуру
19.09.16
12:45
(27) ну, я не уверен, что план закэшируется для разных соединений. в цикле - да, ускоряется.
30 spock
 
19.09.16
12:46
(29) судя из (0) речь, как раз, идет про цикл.
31 DrZombi
 
гуру
19.09.16
12:46
(23) Ваш термин "Подготовка" и "Два запроса", немного смущает. И думается , что вы не понимаете, что от вас хотят :)
32 spock
 
19.09.16
12:47
(31) да все он нормально говорит, кто в теме, тот поймет :)
33 spock
 
19.09.16
12:54
+32 https://msdn.microsoft.com/en-us/library/ms675101(v=vs.85).aspx
"Therefore, commands should be prepared only if they will be used more than one time."
34 Fragster
 
гуру
19.09.16
13:03
(33) а вот лично мое ИМХО в том, что преимущества от избавления от экранирования перебивают "второй запрос".
35 spock
 
19.09.16
13:06
(34) пардон, мысль этого ИМХО не уловил.
36 spock
 
19.09.16
13:08
+35 если речь про то, что подготовленные запросы не дают больших преимуществ в скорости, то отчасти правда.
37 Fragster
 
гуру
19.09.16
13:52
(36) речь про то, что не надо Формат() для чисел и дат, не надо экранирования кавычек для строк.
Время на подготовку параметров для запроса и время подготовки выражения могут быть сопоставимы, но дело не в этом, а в том, что код получается более лаконичным, наглядным и менее "вермишелистым".
38 DrZombi
 
гуру
19.09.16
14:00
(33) Вот оно как Мехалыч... :)
39 DrZombi
 
гуру
19.09.16
14:02
(37) Классс... а код тут причем? О)
Для кого он нагляден? Для человека как то фиолетово, понял код он или нет :)
Машина разве его плохо переваривает?
40 Fragster
 
гуру
19.09.16
14:05
(39) «Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живете» — Макконнелл, Стив.
41 Fragster
 
гуру
19.09.16
14:05
вот вернешься ты к этому месту через пол года...
42 spock
 
19.09.16
14:24
(40) +100
43 Necessitudo
 
19.09.16
14:42
(0) Никак. Предлагаю альтернативу - разработчики в Оракле тебе делают http-сервис, который на вход принимает строку с запросом, и выполняет его. У нас так работало.
44 sapphire
 
19.09.16
14:46
(1) Давно
45 DrZombi
 
гуру
19.09.16
15:08
(40) Больно надо... Не, ну конечно можно написать код на уровне "привет МИР", но оно мне надо? :)
Компьютер — устройство, разработанное для ускорения и автоматизации человеческих ошибок.