Просто хотел поделиться своим решением для Pyspark - это более или менее перевод решения @David Griffin, поэтому он поддерживает любой уровень вложенных объектов.
from pyspark.sql.types import StructType, ArrayType
def flatten(schema, prefix=None):
fields = []
for field in schema.fields:
name = prefix + '.' + field.name if prefix else field.name
dtype = field.dataType
if isinstance(dtype, ArrayType):
dtype = dtype.elementType
if isinstance(dtype, StructType):
fields += flatten(dtype, prefix=name)
else:
fields.append(name)
return fields
df.select(flatten(df.schema)).show()
Я не фанат Oracle, поэтому не могу проверить - но это звучит так, будто они передаются по позиции (а не по имени). Моральный эквивалент:
EXEC SomeProc 'Foo', 'Bar'
вместо:
EXEC SomeProc @arg1='Foo', @arg2='Bar'
. Это не такая уж редкость - в течение многих лет (во времена COM) большая часть моего кода должна была работать с драйвером ADODB, работающим отдельно от других позиций.
В этом случае имя, которое вы даете, служит только как локальный ключ для поиска значения из коллекции коллекции. Вы можете легко проверить, придумав имя:
cmd.Parameters.Add(new OracleParameter("BANANA", ...
cmd.Parameters.Add(new OracleParameter("GUITAR", ...
...
cmd.Parameters["BANANA"].Value.ToString()
cmd.Parameters["GUITAR"].Value.ToString()
Если вышеприведенное выполняется без ошибок, оно передается по позиции. И если они передаются по позиции ... тогда просто добавьте их в правильном порядке ;-p И никогда не добавляйте новые параметры, кроме как в конце ...
Не ответ на вопрос, но вы можете использовать 'insert ... return ... into' вместо select bgt_sequence.currval из dual, например:
begin
insert into test (id)
values(test_seq.nextval)
returning id into p_id;
end;
См. http://www.adp-gmbh.ch/ora/sql/insert_into_x_returning_y.html
Вероятно, вы можете установить параметр BindByName для объекта OracleCommand. Это работает для прямых SQL-запросов с параметрами, я не пробовал это с хранимыми процедурами, но было бы логично ...
cmd.BindByName = true;