尝试传递自定义 oracle 类型对象映射时的名称模式无效

Posted

技术标签:

【中文标题】尝试传递自定义 oracle 类型对象映射时的名称模式无效【英文标题】:invalid name pattern when trying to pass custom oracle type object mapping 【发布时间】:2014-03-02 14:04:58 【问题描述】:

我正在尝试使用 Java spring 自定义 Oracle 类型作为参数并收到以下错误:

org.springframework.jdbc.UncategorizedSQLException: 
### Error updating database.  Cause: java.sql.SQLException: invalid name pattern: UPSELL.mkt_list_tab
### The error may involve com.comcast.upsell.dao.ProviderAndRegionalDao.getCorpsToMarketsList-Inline
### The error occurred while setting parameters
### SQL: call upsell_tx_etl_report.GET_OFFER_CORPS_TO_MARKETS(   ?,   ?,   ?   )
### Cause: java.sql.SQLException: invalid name pattern: MY_SCHEMA.mkt_list_tab
; uncategorized SQLException for SQL []; SQL state [99999]; error code [17074]; invalid name pattern: MY_SCHEMA.mkt_list_tab; nested exception is java.sql.SQLException: invalid name pattern: MY_SCHEMA.mkt_list_tab
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:83)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
    at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:71)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:364)
    at com.sun.proxy.$Proxy15.update(Unknown Source)

我不明白:无效的名称模式是什么意思?

这是我的 Oracle 类型声明:

create or replace 
type mkt_list_tab is table of mkt_list_rec

create or replace 
type mkt_list_rec as object
    (
    market  VARCHAR2(100)
    )

过程调用如下:

PROCEDURE GET_OFFER_CORPS_TO_MARKETS(p_division              IN VARCHAR2, --ALL/Particular
                                     p_market_list           IN mkt_list_tab,
                                     o_offer_corp_market_cur OUT SYS_REFCURSOR)

这是我的 Java 类型处理程序:

    public class MarketListTypeHandler implements TypeHandler 
    
        
    
        @SuppressWarnings("unchecked")
        @Override
        public void setParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException 
            
            
            C3P0NativeJdbcExtractor cp30NativeJdbcExtractor = new C3P0NativeJdbcExtractor(); 
            OracleConnection connection = (OracleConnection) cp30NativeJdbcExtractor.getNativeConnection(ps.getConnection()); 
            
            
            List<StoredProcedurePojo> objects = (List<StoredProcedurePojo>) parameter;
    
            StructDescriptor structDescriptor = StructDescriptor.createDescriptor("mkt_list_rec", connection);
    
            STRUCT[] structs = new STRUCT[objects.size()];
            for (int index = 0; index < objects.size(); index++)
            
                StoredProcedurePojo pack = objects.get(index);
                Object[] params = new Object[2];
                params[0] = pack.getMarket();
                STRUCT struct = new STRUCT(structDescriptor, ps.getConnection(), params);
                structs[index] = struct;
            
    
            ArrayDescriptor desc = ArrayDescriptor.createDescriptor("mkt_list_tab", ps.getConnection());
            ARRAY oracleArray = new ARRAY(desc, ps.getConnection(), structs);
            ps.setArray(i, oracleArray);
        


@Override
        public Object getResult(ResultSet arg0, String arg1) throws SQLException 
            // TODO Auto-generated method stub
            return null;
        
    
        @Override
        public Object getResult(ResultSet arg0, int arg1) throws SQLException 
            // TODO Auto-generated method stub
            return null;
        
    
        @Override
        public Object getResult(CallableStatement arg0, int arg1) throws SQLException 
            // TODO Auto-generated method stub
            return null;
        
    
        
        
        public MarketListTypeHandler() 
            super();
            // TODO Auto-generated constructor stub
        

这是我的存储过程 pojo 类:

public class StoredProcedurePojo 


    private String market;

    public String getMarket() 
        return market;
    

    public void setMarket(String market) 
        this.market = market;
    
    
    

我已尝试遵循此解决方案:

How to Pass Java List of Objects to Oracle Stored Procedure Using MyBatis?

【问题讨论】:

您用于应用的 oracle 用户 ID 无权访问类型 MY_SCHEMA.mkt_list_tab 【参考方案1】:

您用于应用的 oracle 用户 ID 无权访问类型 MY_SCHEMA.mkt_list_tab

还要确保以下几点。

1) 在您的 descriptor 调用中,它必须是所有大写字母,例如 MY_SCHEMA.MKT_LIST_TAB。 2)如果您在代码中不使用架构名称,并且您的应用程序ID与不同的架构相关联,最好为类型(父子类型)创建PUBLIC SYNONYM,并授予EXECUTE权限您的应用程序 ID,否则,使用代码中的架构名称。(仍然需要提供权限)

【讨论】:

是的,这是大写“MKT_LIST_TAB”的问题,我试过这个并为我工作 嗨,我正在尝试在 wso2 dss 中使用类型为 (MY_TYPE) 的包 (MY_PACKAGE),它对我不起作用。我用过:MY_PACKAGE.MY_TYPE(不工作),MY_SCHEMA.MY_PACKAGE.MY_TYPE(不工作)MY_TYPE(不工作)。请指教? MY_TYPEall_objects 中列出? 不,它是输入 MY_PACKAGE,所以我只能在 all_objects 中看到 MY_PACKAGE 所以,是的,PL/SQL 中定义的类型只能在PL/SQL 范围内使用。如您之前提到的,只能使用普通的SQL 类型MY_SCHEMA.MY_PACKAGE.MY_TYPE【参考方案2】:

两件事之一:

    您连接到数据库的 oracle 用户没有执行存储过程的权限。 (不太可能) 您的ArrayDescriptorStructDescriptor 应该分别有大写的"mkt_list_tab""mkt_list_rec"(更有可能)

另见this question。

【讨论】:

【参考方案3】:

我在调用 Oracle 存储过程时遇到了同样的问题:

PACKAGE_NAME.PROCEDURE_NAME(?, ?, ?, ?,?, ?, ?, ?, ?)]; 
13:52:24.202 [main] DEBUG o.s.j.s.SQLStateSQLExceptionTranslator - Extracted SQL state class '99' 
from value '99999' org.springframework.jdbc.UncategorizedSQLException: CallableStatementCallback; 
uncategorized SQLException for SQL [call PACKAGE_NAME.PROCEDURE_NAME(?, ?, ?, ?,?, ?, ?, ?, ?)]; 
SQL state [99999]; error code [17074]; invalid name pattern: SCHEMA.Type_Param; nested exception is java.sql.SQLException: 
***invalid name pattern: SCHEMA.Type_Param***
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:83)
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
        at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:1036)
        at org.springframework.jdbc.core.JdbcTemplate.call(JdbcTemplate.java:1070)
        at org.springframework.jdbc.object.StoredProcedure.execute(StoredProcedure.java:144)

我的程序采用 1 个表格类型的输入参数。此参数是在包级别范围内定义的。所以我将这个包级别的范围参数移动到架构级别参数并解决了这个问题。

在包中创建的 PLSQL 类型不能直接从 java 访问。

【讨论】:

以上是关于尝试传递自定义 oracle 类型对象映射时的名称模式无效的主要内容,如果未能解决你的问题,请参考以下文章

将自定义类型传递给 Oracle 过程

如何使用自定义键值名称将映射列转换为结构类型?

如何为方法 MongoDB.Bson.Serialization.BsonSerializer.Deserialize 自定义映射字段名称或类型

无法在 Intent 中传递自定义对象:方法 Put Extra 对于 Intent 类型不明确

mapstruct使用指南

mybatis基础2