( Также кросс-пост на )
Я знаю, что это старый вопрос, но это один из нескольких, в котором выбранный ответ не решил мою проблему, и я нехочу начать еще одну ветку на эту тему, поэтому я просто опишу то, что нашел в своих путешествиях, в надежде, что это кому-нибудь поможет.Это повторный ответ, потому что я не уверен, что, скорее всего, придет, если кто-то ищет такое решение.
Я мало работаю с Oracle, но, как и в SQL Server, этоКажется, что для передачи табличного параметра вам нужно иметь соответствующий UDT (пользовательская таблица), к которому у вас есть разрешения EXECUTE (я могу ошибаться).Это означает, что другие ответы, предполагающие использование встроенного SYS UDT, идут с некоторым грузом, и я не мог понять, действительно ли возможно передать таблицу чему-то, что не является хранимой процедурой PL / SQL в текущей версииODP.net.
Во-вторых, решение для разбора строк является препятствием по всем очевидным причинам (невозможно кэшировать план выполнения или как его называет Oracle, плохо масштабируется и т. д.).
Так что я потратил довольно много времени, пытаясь выполнить предложение IN, используя табличный параметр в datamart, на который у меня есть только разрешение READ, прежде чем я столкнулся с ослепительной вспышкой очевидного (в ASP)..net на форуме не меньше).Оказывается, Oracle поддерживает Xml-запросы «изначально», поэтому вместо передачи массива значений вы можете передать список XML (если это все, что вам нужно).Опять же, я могу ошибаться, но он обрабатывается как допустимый параметр связывания, и это пример того, как его просто использовать (vb.net, ADO.net, ODP.net с использованием пакета NuGet):
Dim xe As New XElement("l", New XElement("i", "ITEM-A"), New XElement("i", "ITEM-B"))
Using conn As New OracleConnection(myConnectionString)
conn.Open()
Using cmd As OracleCommand = conn.CreateCommand()
cmd.CommandType = CommandType.Text
Dim query As String
query = " SELECT s.FOO, q.BAR " & vbCrLf
query &= " FROM TABLE1 s LEFT OUTER JOIN " & vbCrLf
query &= " TABLE2 q ON q.ID = s.ID " & vbCrLf
query &= " WHERE (COALESCE(q.ID, 'NULL') NOT LIKE '%OPTIONAL%') AND "
query &= " (s.ID IN ("
query &= " SELECT stid "
query &= " FROM XMLTable('/l/i' PASSING XMLTYPE(:stid) COLUMNS stid VARCHAR(32) PATH '.')"
query &= " )"
query &= " )"
cmd.CommandText = query
Dim parameter As OracleParameter = cmd.Parameters.Add("stid", OracleDbType.NVarchar2, 4000)
parameter.Value = xe.ToString
Using r As OracleDataReader = cmd.ExecuteReader
While r.Read()
//Do something
End While
End Using
End Using
conn.Close()
Это скорее наблюдение, чем тщательно изученное решение, поэтому, пожалуйста, прокомментируйте, если есть что-то неуместное в этом.
РЕДАКТИРОВАТЬ.При использовании этого метода, по-видимому, существует ограничение в 4000 символов (2000, если NVARCHAR), поэтому мне пришлось наблюдать за своей страницей.Информативное сообщение об ошибке, которое вы получите, если перейдете, «ORA-01460: запрошено невыполненное или необоснованное преобразование» *