|   |   | 
| 
 | Как передать в ADODB в запрос параметр типа массив? | ☑ | ||
|---|---|---|---|---|
| 0
    
        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 = МТМЦ;>> уже ошибку дает. Как правильно передать параметр? | |||
| 1
    
        Rie 24.04.19✎ 12:24 | 
        Возможно, поможет ComSafeArray.     | |||
| 2
    
        DomovoiAtakue 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(Парам);>> Наверное неправильно задаю данные параметра. Что нужно исправить? | |||
| 3
    
        1Сергей 24.04.19✎ 12:36 | 
        (2) прикольный текст ошибки     | |||
| 4
    
        DomovoiAtakue 24.04.19✎ 12:39 | 
        (3)Ошибка при вызове метода контекста (Append)
 Cmd1.Parameters.Append(Парам); по причине: Произошла исключительная ситуация (ADODB.Parameters): Неправильно определен объект Parameter. Предоставлены несогласованные или неполные сведения. | |||
| 5
    
        arsik гуру 24.04.19✎ 12:40 | 
        Парам.Type = "0x2000"; - там точно строка должна быть?     | |||
| 6
    
        DomovoiAtakue 24.04.19✎ 12:43 | 
        (5)не знаю. А как это записать еще?     | |||
| 7
    
        Кирпич 24.04.19✎ 12:51 | 
        (6) попробуй вместо строки "0x2000" написать число 8192     | |||
| 8
    
        Кирпич 24.04.19✎ 12:53 | 
        а собаку в имени параметра обязательно писать?     | |||
| 9
    
        DomovoiAtakue 24.04.19✎ 12:53 | 
        (7)Нашел тему на форуме где предложили данный вариант, но он не прокатил ни там. ни у меня.
 Ошибка при установке значения атрибута контекста (Type) Парам.Type = 8192; по причине: Произошла исключительная ситуация (ADODB.Parameter): Аргументы имеют неверный тип, выходят за пределы допустимого диапазона или вступают в конфликт друг с другом. | |||
| 10
    
        DomovoiAtakue 24.04.19✎ 12:55 | 
        (8)Не знаю. В статьях в примерах так пишут и я так написал.     | |||
| 11
    
        Кирпич 24.04.19✎ 12:57 | 
        (9) А. Там наверное надо прибавить тип элементов массива     | |||
| 12
    
        DomovoiAtakue 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 | 
        Так заработало или нет?     | |||
| 16
    
        DomovoiAtakue 24.04.19✎ 13:41 | 
        (15)На стадии передачи параметра заработало, но выдало ошибку при выполнении запроса. Вот пытаюсь понять то ли все-таки параметр не так передал то ли что еще?     | |||
| 17
    
        Кирпич 24.04.19✎ 13:58 | 
        ну покажи запрос тогда     | |||
| 18
    
        SSSSS_AAAAA 24.04.19✎ 14:01 | 
        (0) А в каких СУБД есть тип "массив"? СУБД, для которой пишется запрос, входит в этот список?     | |||
| 19
    
        DomovoiAtakue 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): Неизвестное имя типа. | |||
| 20
    
        DomovoiAtakue 24.04.19✎ 14:20 | 
        (18)Не знаю.     | |||
| 21
    
        NorthWind 24.04.19✎ 14:29 | 
        (19) > where p.art in @TMC
 Крутяк. А почему вы решили, что это вообще будет работать? Вы где-то находили рабочий пример для вашей БД, где содержимое IN (...) так передавалось? | |||
| 22
    
        fisher 24.04.19✎ 14:31 | 
        Я когда-то решал эту задачу в MSSQL через XML. Там были встроенные функции, позволяющие одной командой распарсить XML и вернуть результат в виде таблицы. Ну и я в 1С пихал элементы массива в XML, на стороне сиквела конвертировал xml во временную таблицу, ну а дальше уже понятно.     | |||
| 23
    
        NorthWind 24.04.19✎ 14:35 | 
        (22) такой вариант не пробовал, хотя он вполне имеет право на существование.
 Можно решить через временную таблицу - проинсертить в нее параметры, а потом сделать IN (select col from temp_tbl where id=:id) Можно сформировать строку ('aaaa', 'bbb', ...) и потом сформировать с ней запрос, обойдясь без параметров. Но при этом надо помнить, что многие БД имеют ограничение на количество элементов в таком списке. | |||
| 24
    
        NorthWind 24.04.19✎ 14:35 | 
        а вот если бы было возможно (19) - это была бы песня. Но чет мне кажется, что это фантастика.     | |||
| 25
    
        DomovoiAtakue 24.04.19✎ 14:36 | 
        (21)В данной базе нет примеров передачи параметра в запрос. Но если я напишу в запросе вместо параметра IN ('3453','245','64564'), то работает. Внутри скобок по сути массив, ну я и решил что можно передать туда массив и должно заработать.     | |||
| 26
    
        NorthWind 24.04.19✎ 14:38 | 
        (25) я не могу вам привести пруфов, как и вы мне. Но вероятность около 95%, что так сделать не получится. Во всяком случае мне еще не попадался SQL, который позволял бы передавать параметром множество в IN.     | |||
| 27
    
        DomovoiAtakue 24.04.19✎ 14:40 | 
        Понятно. Будем пробовать по-другому :)     | |||
| 28
    
        NorthWind 24.04.19✎ 14:41 | 
        я в такой ситуации либо собирал запрос ручками без параметра (если элементов заведомо не очень много, либо делал через временную таблицу. Вон, (22) еще через XML советует, тоже вариант.     | |||
| 29
    
        fisher 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) ) | 
| Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |