【发布时间】:2019-10-22 02:24:06
【问题描述】:
由于某种原因,DB 没有收到通过表参数给出的值。它看到表中的行数正确,并且给定的列数也是正确的(否则我会收到不匹配的错误),但值本身是空的。
数据库版本(SELECT * FROM V$VERSION):
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
PL/SQL Release 12.1.0.2.0 - Production
"CORE 12.1.0.2.0 Production"
TNS for 64-bit Windows: Version 12.1.0.2.0 - Production
NLSRTL Version 12.1.0.2.0 - Production
使用 oracle 驱动程序 ojdbc6(版本 11.2.0.4)、ojdbc7(版本 11.2.0.4)、ojdbc7(版本 12.1.0.2)测试。
这是 DB 过程的签名:
Procedure Send_Message_Test (
i_Receiver_List_Users_Tbl In Receiver_List_Users_Tbl
);
类型:
CREATE OR REPLACE Type Receiver_List_Users_Rt Force As Object (
User_Id Varchar2(30 Char)
)
/
CREATE OR REPLACE Type Receiver_List_Users_Tbl Is Table Of Receiver_List_Users_Rt
这是调用它的最小完整 Java Spring Boot 应用程序:
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 http://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>1.5.14.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.test</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>test</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.4</version>
</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>
</plugin>
</plugins>
</build>
</project>
src/main/resources/application.properties
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.url=jdbc:oracle:thin:@192.168.1.233:1521/sis1
spring.datasource.username=<omitted>
spring.datasource.password=<omitted>
spring.datasource.tomcat.test-while-idle=true
spring.datasource.tomcat.test-on-borrow=true
spring.datasource.tomcat.test-on-return=false
spring.datasource.tomcat.validation-query=select 1 from dual
spring.datasource.tomcat.max-active=100
spring.datasource.tomcat.max-wait=10000
spring.datasource.tomcat.remove-abandoned-timeout=60
spring.datasource.tomcat.remove-abandoned=true
spring.datasource.tomcat.log-abandoned=true
src/main/java/com/test/test/TestApplication.java
package com.test.test;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.Statement;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.jdbc.datasource.DataSourceUtils;
import oracle.sql.ARRAY;
import oracle.sql.ArrayDescriptor;
import oracle.sql.STRUCT;
import oracle.sql.StructDescriptor;
@SpringBootApplication
public class TestApplication implements ApplicationRunner {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
@Autowired
DataSource dataSource;
@Override
public void run(ApplicationArguments args) throws Exception {
Connection conn = DataSourceUtils.getConnection(dataSource);
CallableStatement callStmt = null;
Statement alterDateFormatStmt = conn.createStatement();
alterDateFormatStmt.execute("alter session set NLS_DATE_FORMAT = 'YYYY-MM-DD'");
alterDateFormatStmt.close();
// create PLSQL procedure statement
String stmStr = "{call Notification_Manage_v2.Send_Message_Test (?)}";
// create Oracle statement and set parameters
callStmt = conn.prepareCall(stmStr);
StructDescriptor recordDescriptor = StructDescriptor.createDescriptor("RECEIVER_LIST_USERS_RT",
callStmt.getConnection());
ArrayDescriptor arrayDescriptor = ArrayDescriptor.createDescriptor("RECEIVER_LIST_USERS_TBL",
callStmt.getConnection());
callStmt.setObject(1, new ARRAY(arrayDescriptor, callStmt.getConnection(),
new STRUCT[] { new STRUCT(recordDescriptor, callStmt.getConnection(), new Object[] { "test" }) }));
callStmt.execute();
}
}
但是,运行这个之后,这是我在Transactions 表Param_values 列中看到的:
i_Receiver_List_Users_Tbl => Receiver_List_Users_Tbl(Receiver_List_Users_Rt ())
任何见解将不胜感激。
这是从 DB 端形成 param_values 列的方式:
CREATE OR REPLACE Type Receiver_List_Users_Rt Force As Object (User_Id Varchar2(30 Char));
CREATE OR REPLACE Type Receiver_List_Users_Tbl Is Table Of Receiver_List_Users_Rt;
Procedure Send_Message_Test (i_Receiver_List_Users_Tbl In Receiver_List_Users_Tbl
) Is
--
tbl_Receiver_List_Users Receiver_List_Users_Tbl := Receiver_List_Users_Tbl();
v_Param_Receiver_List_Users Varchar2(3000);
--
Begin
--
For e_Usr In (Select t_Receiver_List_Users.User_Id User_Id
From Table(i_Receiver_List_Users_Tbl) t_Receiver_List_Users
) Loop
--
v_Param_Receiver_List_Users := v_Param_Receiver_List_Users ||
Case When v_Param_Receiver_List_Users Is Not Null Then ', ' End||
'Receiver_List_Users_Rt ('||e_Usr.User_Id||')';
--
End Loop;
--
If v_Param_Receiver_List_Users Is Not Null Then
v_Param_Receiver_List_Users := 'Receiver_List_Users_Tbl('||v_Param_Receiver_List_Users||')';
End If;
--
--
dbms_output.put_Line('i_Receiver_List_Users_Tbl => '||v_Param_Receiver_List_Users); -- !!!!!!!! no values receive
--
--
End;
【问题讨论】:
-
但是,运行这个之后,这是我在 Transactions 表 Param_values 列中看到的内容 我错过了什么?
Transactionstable 和Param_values不会出现在您发布的代码中的任何位置。 -
@Abra 嗯我想我错误地认为它是一个默认/系统表。无论如何,与 DB 合作的人抱怨说她从我的 java 端接收到空值,我被告知使用
Transactions表自己查看 -
在任何一种情况下,我都希望
Transactions不应该是罪魁祸首,因为当使用 sql 调用该过程时,它会显示正确的预期参数值。不过,我会在星期一回来工作时询问它的定义 -
你用的是什么java版本?你在使用 Oracle 的 JDBC 驱动程序吗?如果有,是哪个版本?如果不是,那么您使用的是哪个 JDBC 驱动程序?
-
编辑的驱动程序版本
标签: java oracle spring-boot plsql