我有一个
Oracle PL/SQL
程序,我可以直接调用如下,没有问题:
BEGIN
example_package_name.example_procedure(p_item_no => 123456, p_send_now => true);
END;
(注意:
p_item_no
期望a
NUMBER
和
p_send_now
期望a
BOOLEAN
)
我正在尝试运行这个从我的
Robot Framework
测试自动化框架中,如下所示。
首先,我有一个小的帮助器包装方法
robotframework-databaselibrary
:
Execute SQL stored procedure
[Arguments]
... ${target_database}
... ${target_stored_procedure}
... ${stored_procedure_arguments}
... ${timeout}=5 minutes
[Documentation] Small wrapper around DatabaseLibrary for the: Call stored procedure keyword.
[Timeout] ${timeout}
__Open connection to target database ${target_database}
DatabaseLibrary.Set Auto Commit autoCommit=${True}
DatabaseLibrary.Call Stored Procedure ${target_stored_procedure} ${stored_procedure_arguments}
Close connection from the current database
接下来,我在测试中尝试如下操作:
${item_no_int}= Convert To Integer ${test_item_dictionary.item_no}
${example_procedure_argument_list}= Create List p_item_no => ${item_no_int} p_send_now => ${True}
Execute SQL Stored Procedure target_database=test_db_name target_stored_procedure=example_package_name.example_procedure stored_procedure_arguments=${example_procedure_argument_list}
我的错误如下:
[info (+0.10s)] 执行:调用存储过程 | 示例程序包名称.示例程序 | ['p_item_no => 123456', 'p_send_now => True']
[FAIL] DatabaseError:ORA-06502: PL/SQL: 数字或值错误:字符到数字转换错误 ORA-06512: 在第 1 行帮助: https://docs.oracle.com/error-help/db/ora-06502/
自然,在离开Robot Framework、阅读文档时,我一直在努力确保我的数据是正确的类型在机器人框架上:
DatabaseLibrary.Call Stored Procedure
关键字,我看到:
def call_stored_procedure(
self, spName: str, spParams: Optional[List[str]] = None, sansTran: bool = False, alias: Optional[str] = None
):
带有描述:
调用存储过程
spName
与spParams
- a 列表 过程所需的参数。
关键字
DatabaseLibrary.Call Stored Procedure
/
spParams: Optional[List[str]]
是否有可能最终没有保留预期的数据类型?或者我可能缺少其他东西?
我正在运行:
-
robotframework>=7.0.0
-
robotframework-databaselibrary>=1.4.3
-
oracledb>=2.1.0
问题在于
DatabaseLibrary.Call Stored Procedure
关键字,当你传递一个字符串列表作为参数时,它不会自动推断数据类型。所有参数都被视为字符串,导致Oracle在试图将字符串值
'123456'
插入到一个应该包含数字的列时抛出“字符到数字转换错误”。
你有几个选择可以解决这个问题:
1. 在PL/SQL代码中进行转换:
-
最简单的解决方案是在PL/SQL存储过程中处理类型转换。修改你的存储过程以接受字符串参数,并在过程中进行显式转换:
sql BEGIN example_package_name.example_procedure( p_item_no => TO_NUMBER(:p_item_no), p_send_now => CASE :p_send_now WHEN 'True' THEN 1 ELSE 0 END ); END;
- 然后,你可以像现在这样传递参数,而无需在Robot Framework中进行任何转换。
2. 使用绑定变量:
- 你可以利用Oracle数据库连接的绑定变量功能。这允许你将变量及其数据类型传递给数据库驱动程序,然后驱动程序将处理正确的转换。
-
不幸的是,
DatabaseLibrary.Call Stored Procedure
关键字不支持绑定变量。你需要使用Execute SQL String
关键字并自己构造SQL语句:robotframework ${sql} Set Variable BEGIN example_package_name.example_procedure(p_item_no => :1, p_send_now => :2); END; ${result} Execute SQL String ${sql} ${item_no_int} ${True}
- 这种方法需要更多的手动工作,但提供了更好的类型安全性和性能,因为它避免了字符串连接和SQL注入的风险。
3. 使用不同的数据库库:
- 探索其他Robot Framework数据库库,这些库可能对存储过程调用提供更好的支持,包括数据类型处理和绑定变量。
对于你的代码,我建议使用绑定变量方法(选项2),因为它提供了更好的类型安全性和性能。
标签:python,oracle,plsql,robotframework From: 78328798