错误 PLS-00302:在 Oracle 中使用自定义类型时必须声明“DBMS_PICKLER”组件

问题描述 投票:0回答:1

我在 Oracle 中遇到 DBMS_PICKLER 包的问题。创建自定义类型后

create type     NUM_ARRAY is varray(100) of NUMBER;

我收到以下异常:

Caused by: oracle.jdbc.OracleDatabaseException: ORA-06550: line 1, column 17:
PLS-00302: component 'DBMS_PICKLER' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

请注意,当我想从 Java 代码调用函数/过程时,就会出现问题。然而,当我直接从 PL/SQL 控制台调用时,一切似乎都是正确的。

CREATE OR REPLACE FUNCTION TEST(P_NUMBER_LIST IN NUM_ARRAY)
    RETURN CLOB
    IS
    RESULT CLOB;
BEGIN

    SELECT JSON_ARRAYAGG(COLUMN_VALUE) INTO RESULT FROM TABLE (P_NUMBER_LIST);

    RETURN RESULT;
EXCEPTION
    WHEN NO_DATA_FOUND THEN RETURN NULL;
END;

SELECT TEST(NUM_ARRAY(1, 2, 3)) FROM DUAL;

下面,我添加了调用 Oracle 函数的 Java 代码。

@Repository
@RequiredArgsConstructor
public class TestDaoImpl implements TestDao {
    private final DataSource dataSource;

    @Override
    public String test(TestRequest request) {
        var caller = new SimpleJdbcCall(dataSource);


        caller.withSchemaName("DIM")
                .withFunctionName("TEST")
                .declareParameters(
                        new SqlParameter("P_NUMBER_LIST", Types.ARRAY, "DIM.NUM_ARRAY"),
                        new SqlOutParameter("RESULT", Types.CLOB)
                );

        var params = new MapSqlParameterSource()
                .addValue("P_NUMBER_LIST", new OracleNumberArray(request.getNumbers()));

        var clob = caller.executeFunction(Clob.class, params); // problem occurs in here
        return clobToString(clob);
    }
}

并为自定义类型创建了 OracleNumberArray 类:

public class OracleNumberArray extends AbstractSqlTypeValue {

    private final List<Long> values;

    public OracleNumberArray(List<Long> values) {
        this.values = isNull(values) ? List.of() : values;
    }

    @Override
    @Deprecated
    public Object createTypeValue(Connection con, int sqlType, String typeName) throws SQLException {
        con = con.unwrap(oracle.jdbc.OracleConnection.class);
        ArrayDescriptor desc = new ArrayDescriptor(typeName, con);
        return new ARRAY(desc, con, values.toArray(new Long[0]));
    }

}

pom.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>io.programming</groupId>
    <artifactId>problems</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>problems</name>
    <description>Solutions for Programming Problems</description>
    <properties>
        <java.version>21</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.oracle.database.jdbc</groupId>
            <artifactId>ojdbc11</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>com.oracle.ojdbc</groupId>
            <artifactId>ojdbc8</artifactId>
            <version>19.3.0.0</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

任何人都可以建议解决这个问题吗?当我尝试使用 DBMS_PICKLER 包时似乎会出现这种情况。

下面我添加了错误的完整堆栈跟踪:https://ctxt.io/2/AACoyLc2EQ

sql oracle plsql plsql-package
1个回答
0
投票

如本博文中所示,如果您连接的用户有一个名为 SYS

 的对象,则可能会发生这种情况。

这会导致

类似的 PLS-00302 错误发生变化;在这种情况下,用户拥有一个与其自己的架构同名的对象。

这里的对象是一个不同的模式,但由于 JDBC 驱动程序显然正在调用

SYS.DBMS_PICKLER.something

,因此发生了相同类型的名称冲突。

名称解析

意味着它优先于模式查看当前用户的SYS对象,因为步骤 1a - “在当前模式中搜索名称与第一部分匹配的对象。”

然后它会尝试使用该 

SYS

对象解析名称的其余部分 - 但它无法做到这一点,因此会导致您看到的错误。

要解决此问题,您需要删除或更改 

SYS

对象的名称。一般来说,避免拥有与任何模式名称以及关键字、保留字等匹配的任何对象。

    

© www.soinside.com 2019 - 2024. All rights reserved.