Java 无法通过Oracle数据库更改通知获取表名

Java 无法通过Oracle数据库更改通知获取表名,java,oracle,jdbc,Java,Oracle,Jdbc,我必须监视多个表的更改。我的数据库是Oracle11g,我使用的是ojdbc6.jar jdbc驱动程序库。问题是当数据库更改事件发生时,我得到的是“?”而不是表名。DatabaseChangeEvent中的所有其他数据都存在,只缺少表名 我正在使用我在互联网上找到的下面的代码,我根据自己的需要稍微修改了一下 这是程序的输出: Connection information : local=ORATEST01/10.10.60.17:43000, remote=ORATEST01/10 .10.

我必须监视多个表的更改。我的数据库是Oracle11g,我使用的是ojdbc6.jar jdbc驱动程序库。问题是当数据库更改事件发生时,我得到的是“?”而不是表名。DatabaseChangeEvent中的所有其他数据都存在,只缺少表名

我正在使用我在互联网上找到的下面的代码,我根据自己的需要稍微修改了一下

这是程序的输出:

Connection information  : local=ORATEST01/10.10.60.17:43000, remote=ORATEST01/10
.10.60.17:52683
Registration ID         : 63
Notification version    : 1
Event type              : OBJCHANGE
Database name           : fmvroratest
Table Change Description (length=1)
    operation=[UPDATE], tableName=???, objectNumber=73786
    Row Change Description (length=2):
      ROW:  operation=UPDATE, ROWID=AAASA6AAHAAACEEAAA
      ROW:  operation=UPDATE, ROWID=AAASA6AAHAAACEEAAA

Table changed: ???




package hr.mspoljaric.dcn;

import java.sql.*;
import java.util.*;
import oracle.jdbc.*;
import oracle.jdbc.dcn.*;

public class OracleDCN {
    String URL = "jdbc:oracle:thin:**********************************";
    Properties prop;

    public static void main(String[] argv) {

        OracleDCN dcn = new OracleDCN();
        try {
            dcn.prop = new Properties();
            dcn.run();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    void run() throws SQLException {
        OracleConnection conn = (OracleConnection) DriverManager.getConnection(
                URL, prop);

        Properties prop = new Properties();
        prop.setProperty(OracleConnection.DCN_NOTIFY_ROWIDS, "true");
        prop.setProperty(OracleConnection.NTF_LOCAL_TCP_PORT, "43000");

        DatabaseChangeRegistration dcr = conn
                .registerDatabaseChangeNotification(prop);

        try {
            dcnListener list = new dcnListener(this);
            dcr.addListener(list);

            Statement stmt = conn.createStatement();
            ((OracleStatement) stmt).setDatabaseChangeRegistration(dcr);
            ResultSet rs = stmt
                    .executeQuery("select 1 from klijent, osobe where 1=2");
            rs.close();
            stmt.close();

        } catch (Exception e) {
            // clean up our registration
            if (conn != null)
                conn.unregisterDatabaseChangeNotification(dcr);
            e.printStackTrace();
        } finally {
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        try {

            Thread.currentThread().join();

        } catch (Exception e) {
            e.printStackTrace();
        }

        finally {
            OracleConnection conn3 = (OracleConnection) DriverManager
                    .getConnection(URL, prop);
            conn3.unregisterDatabaseChangeNotification(dcr);
            conn3.close();
        }
    }
}

class dcnListener implements DatabaseChangeListener {
    OracleDCN dcn;

    dcnListener(OracleDCN dem) {
        dcn = dem;
    }

    public void onDatabaseChangeNotification(DatabaseChangeEvent e) {

        System.out.println(e.toString());

        TableChangeDescription[] tcds = e.getTableChangeDescription();

        for (TableChangeDescription tcd: tcds) 
            System.out.println("Table changed: " + tcd.getTableName());

        synchronized (dcn) {
            dcn.notify();
        }
    }
}

通过以下解决方法解决。因为我得到的是objectNumber作为响应,所以我在这个额外的select中使用这个数字来获取表名:

select object_name from user_objects where object_id=73786

???指示字符集转换错误。“?”是转换过程中发生错误时的标准替换字符。如果您的表名包含非ascii字符,那么这也许可以解释为什么您在通知中看不到它的名称。

不,我严格地只对所有数据库对象标识符使用ascii字符。