|
Отправка "сложных" запрос к 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) Больно надо... Не, ну конечно можно написать код на уровне "привет МИР", но оно мне надо? :)
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |