Вход | Регистрация
 
1С:Предприятие :: 1С:Предприятие 8 общая

Как передать в ADODB в запрос параметр типа массив?

Как передать в ADODB в запрос параметр типа массив?
Я
   DomovoiAtakue
 
24.04.19 - 12:15
Подключаюсь к базе ADODB  и запросом хочу вытащить данные. В запрос мне надо передать строковый массив.

Соединение1 = Новый COMОбъект("ADODB.Connection");
Соединение1.Open(СтрокаСоединения);
Cmd1 = Новый COMОбъект("ADODB.Command");
Cmd1.ActiveConnection = Соединение1;
Cmd1.CommandText = Запрос;

МТМЦ = Новый Массив;
//Заполняем массив строковыми значениями, длина 40 символов.

Парам  = Новый COMОбъект("ADODB.Parameter");
Парам.Name = "@TMC";
Парам.Type = "0x2000";
Парам.Size = МТМЦ.Количество();
Парам.Direction = 1;
Парам.Value = МТМЦ;

Cmd1.Parameters.Append(Парам);

Rs1 = Новый COMОбъект("ADODB.RecordSet");
Rs1 = Cmd1.Execute();


В строке <<Парам.Value = МТМЦ;>> уже ошибку дает. Как правильно передать параметр?
 
 
   Rie
 
1 - 24.04.19 - 12:24
Возможно, поможет ComSafeArray.
   DomovoiAtakue
 
2 - 24.04.19 - 12:35
(1)Помогло. Переписал на:

КомМассив = Новый COMSafeArray(МТМЦ, "VT_BSTR",МТМЦ.Количество());
            
Парам  = Новый COMОбъект("ADODB.Parameter");
Парам.Name = "@TMC";
Парам.Type = "0x2000";
Парам.Size = МТМЦ.Количество();
Парам.Direction = 1;            
Парам.Value = КомМассив;
            
Cmd1.Parameters.Append(Парам);

Теперь ошибка в <<Cmd1.Parameters.Append(Парам);>> Наверное неправильно задаю данные параметра. Что нужно исправить?
   1Сергей
 
3 - 24.04.19 - 12:36
(2) прикольный текст ошибки
   DomovoiAtakue
 
4 - 24.04.19 - 12:39
(3)Ошибка при вызове метода контекста (Append)
            Cmd1.Parameters.Append(Парам);
по причине:
Произошла исключительная ситуация (ADODB.Parameters): Неправильно определен объект Parameter. Предоставлены несогласованные или неполные сведения.
   arsik
 
5 - 24.04.19 - 12:40
Парам.Type = "0x2000"; - там точно строка должна быть?
   DomovoiAtakue
 
6 - 24.04.19 - 12:43
(5)не знаю. А как это записать еще?
   Кирпич
 
7 - 24.04.19 - 12:51
(6) попробуй вместо строки "0x2000" написать число 8192
   Кирпич
 
8 - 24.04.19 - 12:53
а собаку в имени параметра обязательно писать?
   DomovoiAtakue
 
9 - 24.04.19 - 12:53
(7)Нашел тему на форуме где предложили данный вариант, но он не прокатил ни там. ни у меня.

Ошибка при установке значения атрибута контекста (Type)
            Парам.Type = 8192;
по причине:
Произошла исключительная ситуация (ADODB.Parameter): Аргументы имеют неверный тип, выходят за пределы допустимого диапазона или вступают в конфликт друг с другом.
   DomovoiAtakue
 
10 - 24.04.19 - 12:55
(8)Не знаю. В статьях в примерах так пишут и я так написал.
   Кирпич
 
11 - 24.04.19 - 12:57
(9) А. Там наверное надо прибавить тип элементов массива
   DomovoiAtakue
 
12 - 24.04.19 - 12:58
(11)Я не очень понимаю что это и как это? Что мне написать? :)
   Кирпич
 
13 - 24.04.19 - 12:58
попробуй 8192+8
   Кирпич
 
14 - 24.04.19 - 12:59
adBSTR     8     Указывает строку символов с завершающим нулем (Юникод) (DBTYPE_BSTR).

AdArray     0x2000     Значение флага всегда в сочетании с другой константой типа данных, который указывает массив другого типа данных. Не применяется к ADOX.
   Кирпич
 
15 - 24.04.19 - 13:33
Так заработало или нет?
   DomovoiAtakue
 
16 - 24.04.19 - 13:41
(15)На стадии передачи параметра заработало, но выдало ошибку при выполнении запроса. Вот пытаюсь понять то ли все-таки параметр не так передал то ли что еще?
   Кирпич
 
17 - 24.04.19 - 13:58
ну покажи запрос тогда
   SSSSS_AAAAA
 
18 - 24.04.19 - 14:01
(0) А в каких СУБД есть тип "массив"? СУБД, для которой пишется запрос, входит в этот список?
   DomovoiAtakue
 
19 - 24.04.19 - 14:18
(17)Cmd1.CommandText = "SELECT p.group_id,  p.art
            |from ns.products p
            |where p.art in @TMC";

Без условия на параметр запрос работает.
А с параметром выдает ошибку на строке
"Rs1 = Cmd1.Execute();"

Rs1 = Cmd1.Execute();
по причине:
Произошла исключительная ситуация (Provider): Неизвестное имя типа.
   DomovoiAtakue
 
20 - 24.04.19 - 14:20
(18)Не знаю.
   NorthWind
 
21 - 24.04.19 - 14:29
(19) > where p.art in @TMC
Крутяк. А почему вы решили, что это вообще будет работать? Вы где-то находили рабочий пример для вашей БД, где содержимое IN (...) так передавалось?
   fisher
 
22 - 24.04.19 - 14:31
Я когда-то решал эту задачу в MSSQL через XML. Там были встроенные функции, позволяющие одной командой распарсить XML и вернуть результат в виде таблицы. Ну и я в 1С пихал элементы массива в XML, на стороне сиквела конвертировал xml во временную таблицу, ну а дальше уже понятно.
   NorthWind
 
23 - 24.04.19 - 14:35
(22) такой вариант не пробовал, хотя он вполне имеет право на существование.
Можно решить через временную таблицу - проинсертить в нее параметры, а потом сделать IN (select col from temp_tbl where id=:id)
Можно сформировать строку ('aaaa', 'bbb', ...) и потом сформировать с ней запрос, обойдясь без параметров. Но при этом надо помнить, что многие БД имеют ограничение на количество элементов в таком списке.
   NorthWind
 
24 - 24.04.19 - 14:35
а вот если бы было возможно (19) - это была бы песня. Но чет мне кажется, что это фантастика.
   DomovoiAtakue
 
25 - 24.04.19 - 14:36
(21)В данной базе нет примеров передачи параметра в запрос. Но если я напишу в запросе вместо параметра IN ('3453','245','64564'), то работает. Внутри скобок по сути массив, ну я и решил что можно передать туда массив и должно заработать.
   NorthWind
 
26 - 24.04.19 - 14:38
(25) я не могу вам привести пруфов, как и вы мне. Но вероятность около 95%, что так сделать не получится. Во всяком случае мне еще не попадался SQL, который позволял бы передавать параметром множество в IN.
   DomovoiAtakue
 
27 - 24.04.19 - 14:40
Понятно. Будем пробовать по-другому :)
   NorthWind
 
28 - 24.04.19 - 14:41
я в такой ситуации либо собирал запрос ручками без параметра (если элементов заведомо не очень много, либо делал через временную таблицу. Вон, (22) еще через XML советует, тоже вариант.
   fisher
 
29 - 24.04.19 - 14:52
Во, нашел. Лет 5 назад делал, может кому пригодится. Делал только для массива числовых айдишников под свои хранимки, принимающие массив в качестве параметра типа xml. Но, думаю, нетрудно адаптировать и под "голый" sql-скрипт без доп-функций и хранимок.
Функция ПолучитьМассивXML(МассивID) Экспорт
    
    МассивXML = "";
    
    Для Каждого ID Из МассивID Цикл
        МассивXML = МассивXML + "<a e="""+Формат(ID,"ЧГ=0")+"""></a>";
    КонецЦикла;
    
    Возврат МассивXML;
    
КонецФункции

CREATE FUNCTION dbo.get_TableFromXmlArrayOfId(@xmlArray xml)
RETURNS TABLE
AS
RETURN
(
    SELECT xmlArray.id.value('@e','int') AS id
    FROM   @xmlArray.nodes('/a[@e]') xmlArray(id)
)


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