【问题标题】:Error: DPI-1059: bind variables are not supported in DDL statements when call procedure using node-oracledb错误:DPI-1059:使用 node-oracledb 调用过程时,DDL 语句中不支持绑定变量
【发布时间】:2021-07-01 05:21:24
【问题描述】:

我在 sql-developer 中创建了下面的存储过程:

CREATE OR REPLACE PROCEDURE CREATE_USER(
 t_username IN VARCHAR2, 
 t_password IN VARCHAR2,
 t_default_table IN VARCHAR2,
 t_quota IN VARCHAR2
)
IS
    m_statement VARCHAR2(1300);
    
    m_username VARCHAR2(30) := t_username;
    m_password VARCHAR2(30) := t_password;
    m_default_table VARCHAR2(30) := t_default_table;
    m_quota VARCHAR2(30) := t_quota;
    
BEGIN
    m_statement := 'create user ' || t_username || ' identified by ' || t_password;

    IF m_default_table != 'NULL' THEN
         m_statement := m_statement || ' DEFAULT TABLESPACE ' || m_default_table;
    END IF;

    IF m_quota != '0' AND m_default_table != 'NULL' THEN
        m_statement := m_statement || ' QUOTA ' || m_quota || 'M ON ' || m_default_table;
    END IF;
    EXECUTE IMMEDIATE (m_statement);
END;

并且这个编译没有错误。我也连接到oracle。然后我得到了这样的用户数据(req.body):

{ username: 'a', password: 'a', tablespace: 'NULL', quota: '0' }

但是当我执行“调用”过程查询时:

oracle.getConnection(
        {
            uuser : "AN",
            password: "AN123",
            connectString: "localhost:1521/orcl"
        },
        (t_err, t_connection) => {
            if(t_err){
                console.error(t_err);
                return;
            }
            t_connection.execute(
                `BEGIN 
                    createUser(:username, :password, :tablespace, :quota);
                END;`,
                {
                    username: req.body.username,
                    password: req.body.password,
                    tablespace: req.body.tablespace,
                    quota: req.body.quota,
                    
                },
                (t_er, t_reslt) => {
                    if(t_er){
                        console.error(t_er);
                        return;
                    }

我收到了:

[Error: DPI-1059: bind variables are not supported in DDL statements] {
  errorNum: 0,
  offset: 0
}

我尝试了很多方法来修复程序或 nodejs 代码,但没有奏效。我对这个话题很陌生。谁能帮帮我?

【问题讨论】:

  • @wolφi。我已经看到了。我所有的参数都是IN参数。所以我只是为他们分配 Req.body.x 中的值。根据你给我的链接,这是真的吗?
  • 有什么办法不使用dll语句?
  • 我对 node-oracledb 完全不熟悉。你是对的,示例说默认是 in。但是,我很想指定数据类型和方向username: { type: oracledb.STRING, dir: oracle_db.BIND_IN}。此外,我会简化示例,例如首先创建一个具有硬编码名称的表,不带任何参数的过程,然后为表名添加一个参数,然后慢慢地朝着您的示例前进。还请检查使用不同的变量名称,也许其中一个是保留关键字。
  • 还有两种可能:1)在PL/SQL中它被称为CREATE_USER,调用代码使用createUser,但我认为这是一个错字。 2) quota: req.body.quota, 行中是否有多余的逗号?

标签: oracle ddl node-oracledb


【解决方案1】:

您的代码运行对我来说没有错误 - 一旦我修复了 SQL 语句中的名称 CREATE_USER 和 JS 文件中的名称 createUser 之间的冲突。确实确保您没有调用某些先前版本的 PL/SQL 包,该包确实尝试在 CREATE USER 语句中使用绑定变量(这在 cmets 中已注明)。如错误所述:Oracle DB 不支持这种用法。例如,您不能这样做:

connection.execute(`create user :un identified by :pw`, ['cj2', 'cj2password']);
  • 这是一个 DDL 语句
  • 它尝试使用绑定变量

这不受支持。它因 DPI-1059 而失败。绑定变量用于数据,而不是语句的文本。

另外两个提示:

  • 过滤或清理您的输入值以避免 SQL 注入攻击
  • 使用异步/等待风格的编程(而不是回调)来省去一些麻烦。查看所有node-oracledb examples

【讨论】:

    【解决方案2】:

    错误代码DPI-1059 看起来很陌生,不像是Oracle 错误消息。我检查了node-oracledb,他们使用NJS-000NJS-080。谷歌搜索导致 Oracle 的 C 数据库编程接口,它在 dpiErrorMessages.h 中定义了这个错误代码:

    "DPI-1059: bind variables are not supported in DDL statements", // DPI_ERR_NO_BIND_VARS_IN_DDL
    

    常量DPI_ERR_NO_BIND_VARS_IN_DDL在源代码中只使用一次,在文件dpiStmt.c中:

    // attempt to improve message "ORA-01036: illegal variable name/number"
    if (status < 0) {
        if (error->buffer->code == 1036) {
            if (stmt->statementType == DPI_STMT_TYPE_CREATE ||
                    stmt->statementType == DPI_STMT_TYPE_DROP ||
                    stmt->statementType == DPI_STMT_TYPE_ALTER)
                dpiError__set(error, error->buffer->action,
                        DPI_ERR_NO_BIND_VARS_IN_DDL);
        }
        return DPI_FAILURE;
    }
    

    由于 Oracle 的错误信息非常混乱,因此值得关注 ORA-01036,例如 here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-31
      • 2016-03-22
      • 1970-01-01
      • 1970-01-01
      • 2014-10-18
      • 2019-04-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多