Вход | Регистрация


1С:Предприятие :: 1С:Предприятие 8 общая

Отправка "сложных" запрос к Oracle через ADODB

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

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

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

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

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

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

...

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

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


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


ADO и параметры
https://support.microsoft.com/ru-ru/kb/181734
   DrZombi
 
9 - 19.09.16 - 12:15
В общем у АДО есть параметры
   1S_User
 
10 - 19.09.16 - 12:16
(8) Видимо, потому, что те, кому отсылаются подобные запросы, считают, что это не безопасно. Мне не уточняли. Надо и все. :)
 
 Рекламное место пустует
   Fragster
 
11 - 19.09.16 - 12:16
(6) сделать
   1S_User
 
12 - 19.09.16 - 12:16
(11) Как?
   Fragster
 
13 - 19.09.16 - 12:18
(12)
Функция СоздатьКомандуАДО(Соединение, Текст)
    Команда = Новый ComОбъект("ADODB.Command");
    Команда.ActiveConnection = Соединение;
    
    Команда.CommandType = мМагияСКЛ.adCmdText;
    Команда.Prepared = Истина;
    
    Команда.CommandText = Текст;
    Возврат Команда;
КонецФункции
   Fragster
 
14 - 19.09.16 - 12:18
Функция ВыполнитьКомандуАДО(Команда)
    
    Попытка 
        Результат = Команда.Execute();
    Исключение
        Инфо = ИнформацияОбОшибке();
        ВызватьИсключение "Ошибка выполнения команды!" + Символы.ПС + Команда.CommandText + Символы.Пс + ПредставлениеОшибки(Инфо);
    КонецПопытки;
    
    Возврат Результат;
КонецФункции
   Fragster
 
15 - 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 = Выборка.Штрихкод;
        
        ВыполнитьКомандуАДО(Команда);

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

select поле из таблица where ДругоеПоле = "123"
   DrZombi
 
17 - 19.09.16 - 12:19
(15) Вот я ему и привел в (8) такое, только на С++ :)
   DrZombi
 
18 - 19.09.16 - 12:19
+ Его не устроило :)
   Fragster
 
19 - 19.09.16 - 12:20
еще пытался ускорить через асинхронное выполнение, но оно немного глючило на разных драйверах
   Fragster
 
20 - 19.09.16 - 12:20
особенно если больше одного запроса одновременно слать
   Fragster
 
21 - 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 + "!";

        КонецПопытки
    КонецПопытки
КонецПроцедуры
   1S_User
 
22 - 19.09.16 - 12:23
Спасибо, буду пробовать.
   1S_User
 
23 - 19.09.16 - 12:31
Ну, получается, если мы так программно сначала подготавливаем команду, потом вызываем, это будет 2 запроса: 1 на подготовку, другой на использование с параметрами, вместо одного непараметрического?
Убойная оптимизация.
За один запрос, получается, сделать нереально?
   Fragster
 
24 - 19.09.16 - 12:33
(23) 1. безопасность (не трахнуть через sql injection, в случае с 1с - это может сышграть при передаче строк, или строковых представлений чисел >1000 (стандартный выстрел в ногу)).
2. небольшое ускорение - для использования в цикле, как у меня.
   spock
 
25 - 19.09.16 - 12:34
   Fragster
 
26 - 19.09.16 - 12:34
(25) это про хранимки статья
   spock
 
27 - 19.09.16 - 12:42
(23) те, кому запрос уходит, хотят оптимизации построения плана запроса.
   spock
 
28 - 19.09.16 - 12:44
(26) пример про ХП, а применение любое.
   Fragster
 
29 - 19.09.16 - 12:45
(27) ну, я не уверен, что план закэшируется для разных соединений. в цикле - да, ускоряется.
   spock
 
30 - 19.09.16 - 12:46
(29) судя из (0) речь, как раз, идет про цикл.
   DrZombi
 
31 - 19.09.16 - 12:46
(23) Ваш термин "Подготовка" и "Два запроса", немного смущает. И думается , что вы не понимаете, что от вас хотят :)
   spock
 
32 - 19.09.16 - 12:47
(31) да все он нормально говорит, кто в теме, тот поймет :)
   spock
 
33 - 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."
 
 
   Fragster
 
34 - 19.09.16 - 13:03
(33) а вот лично мое ИМХО в том, что преимущества от избавления от экранирования перебивают "второй запрос".
   spock
 
35 - 19.09.16 - 13:06
(34) пардон, мысль этого ИМХО не уловил.
   spock
 
36 - 19.09.16 - 13:08
+35 если речь про то, что подготовленные запросы не дают больших преимуществ в скорости, то отчасти правда.
   Fragster
 
37 - 19.09.16 - 13:52
(36) речь про то, что не надо Формат() для чисел и дат, не надо экранирования кавычек для строк.
Время на подготовку параметров для запроса и время подготовки выражения могут быть сопоставимы, но дело не в этом, а в том, что код получается более лаконичным, наглядным и менее "вермишелистым".
   DrZombi
 
38 - 19.09.16 - 14:00
(33) Вот оно как Мехалыч... :)
   DrZombi
 
39 - 19.09.16 - 14:02
(37) Классс... а код тут причем? О)
Для кого он нагляден? Для человека как то фиолетово, понял код он или нет :)
Машина разве его плохо переваривает?
   Fragster
 
40 - 19.09.16 - 14:05
(39) «Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живете» — Макконнелл, Стив.
   Fragster
 
41 - 19.09.16 - 14:05
вот вернешься ты к этому месту через пол года...
   spock
 
42 - 19.09.16 - 14:24
(40) +100
   Necessitudo
 
43 - 19.09.16 - 14:42
(0) Никак. Предлагаю альтернативу - разработчики в Оракле тебе делают http-сервис, который на вход принимает строку с запросом, и выполняет его. У нас так работало.
   sapphire
 
44 - 19.09.16 - 14:46
(1) Давно
   DrZombi
 
45 - 19.09.16 - 15:08
(40) Больно надо... Не, ну конечно можно написать код на уровне "привет МИР", но оно мне надо? :)


Список тем форума
Рекламное место пустует  Рекламное место пустует
Компьютеры — прекрасное средство для решения проблем, которых до их появления не было.
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Тема не обновлялась длительное время, и была помечена как архивная. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.
Рекламное место пустует