0

我尝试将数据从一个表的字符串字段放入另一个表的数字字段。

如果我在 Oracle SQL Developer 或 Toad 等 IDE 中执行此操作,它可以正常工作,但如果我在我的 java 代码中执行此操作,则会出现错误。

如何解决?

下面有我的例子。

数据库:我创建了两个表 - 带有数字字段的 t_num 和带有 varchar2 字段的 t_str - 并将值放入第二个表 t_str

drop table t_num;
create table t_num(num number(10,2));
drop table t_str;
create table t_str(str varchar2(10));
insert into t_str (str) values('23');
insert into t_str (str) values('2 3');
insert into t_str (str) values('2 3,3 2');
commit;

我还创建了将值从 t_str 放到 t_num 的过程

create or replace procedure put_to_t_num
as
    type t_num_t is table of t_num%rowtype index by binary_integer;
    tn t_num_t;
    n binary_integer := 0;
begin
    delete from t_num;
    --tn := t_num_t();
    for rec in ( select * from t_str )
    loop
        n := n + 1;
        --tn.extend;
        tn(n).num := to_number( regexp_replace( regexp_replace( rec.str, ',', '.'), ' ', '' ) );
    end loop;

    forall i in 1..n
        insert into t_num (
            num
        ) values (
            tn(i).num
        );
        --commit;
end;

网络逻辑服务器:

index.jsp:点击按钮向put.jsp发送请求

<button>click</button>
<script>
document.querySelector("button").addEventListener("click", function () {
    var xhr = new XMLHttpRequest();
    xhr.open("GET", "put.jsp");
    xhr.send(null);
    xhr.onreadystatechange = function () {
        if (xhr.readyState == xhr.DONE && xhr.status == 200) {
            console.log(xhr.responseText);
        }
    }
});
</script>

put.jsp:从具有 jndi 名称 jdbc/test 的数据源获取连接并调用过程 put_to_t_num

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ page import="javax.annotation.Resource"%>
<%!
@Resource(name="jdbc/test")
private DataSource ds = null;
%>
<%@ page import="javax.sql.*"%>
<%@ page import="java.sql.*"%>
<%@ page import="javax.naming.*"%>
<%@ page import="java.util.*"%>

<%
Context ctx = null;
try {
    ctx = new InitialContext();
    ds = (DataSource) ctx.lookup("jdbc/test");
} catch (Exception e) {
    out.print(e.getMessage());
}
Connection con = null;
CallableStatement cstmt = null;
Statement stmt = null;
try {
    //call procedure
    con = ds.getConnection();
    cstmt = con.prepareCall("{call put_to_t_num}");
    cstmt.execute();
    //commit
    stmt = con.createStatement();
    stmt.executeUpdate("commit");
    out.print("success");
} catch (SQLException e) {
    out.print("catch error:\n" + e.getMessage());
} finally {
    try {
        if (cstmt != null) {
            cstmt.close();
        }
        if (stmt != null) {
            stmt.close();
        }
        if (con != null) {
            con.close();
        }
    } catch (Exception e) {
        out.print("finally error:\n" + e.getMessage());
    }
}
%>

最后我在浏览器控制台中遇到错误:

catch error:
ORA-06502: PL/SQL: numeric or value error: character to number conversion error
ORA-06512: at "TEST_USER.PUT_TO_T_NUM", line 13
ORA-06512: at line 1

但是如果我在 IDE 中做这样的事情,它工作得很好

begin
    put_to_t_num;
    commit;
end;

我想这可能是编码的情况,但我无法在我的 java 代码中解决它。

select * from nls_database_parameters;

NLS_LANGUAGE    AMERICAN
NLS_TERRITORY   AMERICA
NLS_CURRENCY    $
NLS_ISO_CURRENCY    AMERICA
NLS_NUMERIC_CHARACTERS  .,
NLS_CHARACTERSET    AL32UTF8
NLS_CALENDAR    GREGORIAN
NLS_DATE_FORMAT DD-MON-RR
NLS_DATE_LANGUAGE   AMERICAN
NLS_SORT    BINARY
NLS_TIME_FORMAT HH.MI.SSXFF AM
NLS_TIMESTAMP_FORMAT    DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT  HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY   $
NLS_COMP    BINARY
NLS_LENGTH_SEMANTICS    BYTE
NLS_NCHAR_CONV_EXCP FALSE
NLS_NCHAR_CHARACTERSET  AL16UTF16
NLS_RDBMS_VERSION   11.2.0.2.0

如何解决这个问题?

我还发现,如果没有将值 2 3,3 2 添加到 t_str - 我得到了“成功”。

我该如何处理这种情况?

为什么IDE会这样做,而java代码却不这样做?

4

0 回答 0