Как вызвать процедуру с типом аргумента XMLType? Ошибка: PLS-00306: wrong number or types of arguments in call to
Есть процедура, которая принимает одним из аргументов XMLType:
create or replace procedure p (a in XMLType, b out number) as
begin
b := a.getRootElement();
end;
Взял пример с официального сайта cx_Oracle, и пытаюсь так вызвать процедуру:
xmldata = """<?xml version="1.0"?>
<customer>
<name>John Smith</name>
<Age>43</Age>
<Designation>Professor</Designation>
<Subject>Mathematics</Subject>
</customer>"""
root = cursor.var(str)
xmlval = cursor.var(cx_Oracle.CLOB)
xmlval.setvalue(0, xmldata)
cursor.callproc ('p', [xmlval, root])
Но выдаёт ошибку:
Traceback (most recent call last):
File "test.py", line 19, in <module>
cursor.callproc ('p', [xml, root])
cx_Oracle.DatabaseError: ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'P'
Как можно вызвать процедуру с типом аргумента XMLType?
Ответы (1 шт):
Автор решения: 0xdb
→ Ссылка
Пример из документации описывает поведение в SQL контексте, где допустимо задавать для колонок с типом XMLType символьные литералы:
create table t (a XMLType)
/
insert into t values ('<tag>aaa</tag>')
/
1 row inserted.
в PL/SQL контексте это недопостимо и конструктор должен быть вызван явно:
var b varchar2(32)
exec p ('<tag>aaa</tag>', :b)
PLS-00306: wrong number or types of arguments in call to 'P'
exec p (XMLType ('<tag>aaa</tag>'), :b)
B
---
tag
Так как XMLType нативно не поддерживается в cx_Oracle, то надо процедуру вызвать в анонимном блоке и передать только значение для XMLType как CLOB параметер и вызвать с ним конструктор.
Воспроизводимый пример:
cursor = cx_Oracle.connect ('connect_string').cursor()
xmldata = """<?xml version="1.0"?>
<customer>
<name>John Smith</name>
</customer>"""
root = cursor.var (str)
xml = cursor.var (cx_Oracle.CLOB)
xml.setvalue(0, xmldata)
cursor.execute ("begin p (XMLType(:x), :r); end;", [xml, root])
print (f"root is {root.getvalue()}")
# root is customer