【发布时间】:2014-06-14 16:16:57
【问题描述】:
我正在尝试使用 SimpleJDBCCall 执行 oracle 存储过程,所有表和存储过程都在餐厅模式中,表如下所示:
CREATE TABLE STAFF
(
STAFF_ID NUMBER(5),
STAFF_FIRST_NAME VARCHAR2(10 BYTE) NOT NULL,
STAFF_LAST_NAME VARCHAR2(20 BYTE) NOT NULL,
STAFF_ROLE VARCHAR2(20 BYTE) NOT NULL,
STAFF_OTHER_DETAILS VARCHAR2(50 BYTE)
);
我的类型包:
CREATE OR REPLACE PACKAGE Staff_Types
AS
TYPE Staff_Collection IS TABLE OF Staff%ROWTYPE;
END Staff_Types;
我的访问包:
CREATE OR REPLACE PACKAGE Staff_TAPI
AS
FUNCTION getAllStaff RETURN Staff_Types.Staff_Collection;
END Staff_TAPI;
CREATE OR REPLACE PACKAGE BODY Staff_Tapi
AS
FUNCTION getAllStaff
RETURN Staff_Types.Staff_Collection
IS
all_staff Staff_Types.Staff_Collection;
BEGIN
SELECT *
BULK COLLECT INTO all_staff
FROM Staff;
RETURN all_staff;
END;
END Staff_Tapi;
Java 访问:
@Component
@Qualifier("staffJdbcDAO")
public class StaffJDBCDAO implements StaffDAO {
JdbcTemplate jdbcTemplate;
SimpleJdbcCall getAllMembersSP;
@Autowired
@Qualifier("dataSource")
DataSource dataSource;
@Autowired
@Qualifier("jdbcTemplate")
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
initializeStoredProceduresCalls();
}
private void initializeStoredProceduresCalls() {
getAllMembersSP = new SimpleJdbcCall(jdbcTemplate);
getAllMembersSP.withCatalogName("Staff_Tapi");
getAllMembersSP.withFunctionName("getAllStaff");
getAllMembersSP.declareParameters(
new SqlOutParameter("return",
Types.OTHER,
"Staff_Types.Staff_Collection",
new SqlReturnStructArray<>( new StaffMapper() )
)
);
getAllMembersSP.compile();
}
@Override
public List<Staff> getAllMembers() {
Staff[] staff = getAllMembersSP.executeFunction(Staff[].class,new HashMap<String,Object>() );
return Arrays.asList(staff);
}
}
映射类:
public class StaffMapper implements StructMapper<Staff> {
@Override
public STRUCT toStruct(Staff staff, Connection connection, String typeName) throws SQLException {
StructDescriptor descriptor = StructDescriptor.createDescriptor(typeName, connection);
Object[] attributes = new Object[5];
attributes[0] = new Integer( staff.getId() );
attributes[1] = new String("STAFF_FIRST_NAME");
attributes[2] = new String("STAFF_LAST_NAME");
attributes[3] = new String("STAFF_ROLE");
attributes[4] = new String("STAFF_OTHER_DETAILS");
Struct staffStruct = connection.createStruct(typeName,attributes);
return new STRUCT(descriptor,connection,attributes);
}
@Override
public Staff fromStruct(STRUCT struct) throws SQLException {
StructDescriptor descriptor = struct.getDescriptor();
ResultSetMetaData metaData = descriptor.getMetaData();
Object[] attributes = struct.getAttributes();
Map<String,Object> attributeMap = new HashMap<>();
int idx = 1;
for ( Object attribute : attributes )
attributeMap.put( metaData.getColumnName(idx++),attribute );
int id = ((Integer)attributeMap.get("STAFF_ID")).intValue();
String firstName = (String) attributeMap.get("STAFF_FIRST_NAME");
String lastName = (String) attributeMap.get("STAFF_LAST_NAME");
String staffRole = (String) attributeMap.get("STAFF_ROLE");
String otherDetails = (String) attributeMap.get("STAFF_OTHER_DETAILS");
return new Staff(id,firstName,lastName,staffRole,otherDetails);
}
}
和工作人员:
public class Staff {
private int id;
private String firstName;
private String lastName;
private String profession;
private String otherDetails;
public Staff(int id, String firstName, String lastName, String profession, String otherDetails) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.profession = profession;
this.otherDetails = otherDetails;
}
public int getId() {
return id;
}
public int setId(int id) {
this.id = id;
}
// and others getters and setters
}
当我从 StaffDAO 执行 getAllMembers 时,我不断得到: CallableStatementCallback; SQL 的未分类 SQLException [{? = 调用 STAFF_TAPI.GETALLSTAFF()}]; SQL 状态 [99999];错误代码 [17004];无效的列类型:1111;
当我将返回类型参数更改为 Types.Array 时,我得到:
CallableStatementCallback; SQL 的未分类 SQLException
[{? = 调用 STAFF_TAPI.GETALLSTAFF()}];
SQL 状态 [99999];错误代码 [17074];
无效的名称模式:restaurant.Staff_Types.Staff_Collection;
我尝试了两种方式,模式“Staff_Types.Staf_collection”得到了相同的结果,我尝试了将近 2 天,但不知道我该怎么做,如果有人有任何建议,我会很感激。
【问题讨论】:
-
我似乎记得无法通过 jdbc 引用包类型,并且必须显式使用
CREATE TYPE(模式对象)才能引用。我认为数据字典将包类型名称显示为名称的一些错误版本。但是我已经有几年没有使用 Oracle 了,所以我可能会为此吃午饭。 -
感谢 Glenn 的快速回答。我试过了,但结果和以前完全一样。
标签: java sql spring oracle jdbc