从 Python 向 SQLPlus 脚本传递参数

Posted

技术标签:

【中文标题】从 Python 向 SQLPlus 脚本传递参数【英文标题】:Passing parameters to SQLPlus script from Python 【发布时间】:2021-07-06 16:07:34 【问题描述】:

我正在尝试将变量从 python 脚本传递到 PL/SQLscript。 但我收到“SP2-0310:无法打开文件”错误

下面是代码:

def runSqlQuery():
    connectString = '<username>/"<password>"@//MYHOST:1521/TEST'
    var1=input('Enter VAR1: ')
    var2=input('Enter VAR2: ')
    session = ['sqlplus', '-S', connectString,f'@a.sql var1 var2']
    subprocess.call(session)
runSqlQuery()

SET SERVEROUTPUT ON
 DECLARE
    TYPE usr IS VARRAY(100) OF VARCHAR2(100);
    v_new_rw_user           usr:=usr('&1');
    v_obj_owner             usr:=usr('&2');
 BEGIN
    FOR j IN v_new_rw_user.first..v_new_rw_user.last
    LOOP
        DBMS_OUTPUT.PUT_LINE('Read Only User : ' || UPPER(v_new_rw_user(j)) ||CHR(10));
        FOR i IN v_obj_owner.first..v_obj_owner.last
        LOOP
            DBMS_OUTPUT.PUT_LINE(CHR(10)||'Database Schema : ' || UPPER(v_obj_owner(i)) ||CHR(10));
        END LOOP;
    END LOOP;
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE(CHR(10)||'ERROR CODE : ' || SQLCODE ||CHR(10) || 'ERROR MESSAGE: '|| SQLERRM || CHR(10));
END;
/
EXIT;


Appreciate any help. Thanks in advance

【问题讨论】:

a.sql 定义在哪里? a.sql 与 python 脚本放置在同一位置。我能够在不从 python 传递变量的情况下运行 plsql,其中在调用 plsql 脚本时提供了变量。但我的要求是从 python 脚本传递变量 【参考方案1】:

在tutorial 的帮助下,下面的代码可以工作

TestSQPPlus.py

from subprocess import Popen, PIPE

def runSqlQuery():
    connectString = '<username>/"<password>"@//MYHOST:1521/TEST'
    var1=input('Enter VAR1: ')
    var2=input('Enter VAR2: ')
    sqlCommand = f'@a.sql var1 var2'
    print(sqlCommand)
    session =  Popen(['sqlplus', '-S', connectString], stdin=PIPE, stdout=PIPE, stderr=PIPE)
    session.stdin.write(sqlCommand.encode())
    return session.communicate()
    
queryResult, errorMessage = runSqlQuery()
print(queryResult)
print(errorMessage)

a.sql

SET SERVEROUTPUT ON
 DECLARE
    TYPE usr IS VARRAY(100) OF VARCHAR2(100);
    v_new_rw_user           usr:=usr('&1');
    v_obj_owner             usr:=usr('&2');
 BEGIN
    FOR j IN v_new_rw_user.first..v_new_rw_user.last
    LOOP
        DBMS_OUTPUT.PUT_LINE('Read Only User : ' || UPPER(v_new_rw_user(j)) ||CHR(10));
        FOR i IN v_obj_owner.first..v_obj_owner.last
        LOOP
            DBMS_OUTPUT.PUT_LINE(CHR(10)||'Database Schema : ' || UPPER(v_obj_owner(i)) ||CHR(10));
        END LOOP;
    END LOOP;
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE(CHR(10)||'ERROR CODE : ' || SQLCODE ||CHR(10) || 'ERROR MESSAGE: '|| SQLERRM || CHR(10));
END;
/
quit

执行示例(为简洁和格式化输出剪切)

python TestSQPPlus.py
Enter VAR1: x
Enter VAR2: y

Read Only User : X
Database Schema : Y
PL/SQL-Prozedur erfolgreich abgeschlossen.

注意 - 如果您想在 VARRAY 中输入更多元素,您必须 inject 如下(在自己的 risc 中使用)

python TestSQPPlus.py
Enter VAR1: x1','x2
Enter VAR2: y1','y2
@a.sql x1','x2 y1','y2

Read Only User : X1
Database Schema : Y1
Database Schema : Y2
Read Only User : X2
Database Schema : Y1
Database Schema : Y2
PL/SQL-Prozedur erfolgreich abgeschlossen.

【讨论】:

谢谢,它成功了。但是很好奇使用上面的风险是什么 @Rajesh,请检查标题“SQL 注入”下的内容,您会发现很多解释。您也可以接受答案;) 我确实使用了答案:)。谢谢 如果你觉得答案有用,你也可以accept它;)@Rajesh

以上是关于从 Python 向 SQLPlus 脚本传递参数的主要内容,如果未能解决你的问题,请参考以下文章

从 Shell 脚本向 Python 传递参数

shell调用python脚本,并且向python脚本传递参数

将变量从 Powershell 脚本传递到 SQLPlus

从 bash 脚本中将日期传递给 sqlplus 命令

将参数从 CMD 文件传递​​到 SQL 脚本

参数传递:shell脚本调用一个带参数的python函数