java代码和oracle db服务器上的查询结果不同:但没有连接错误
我有连接到远程oracle 11g EE db服务器的java代码。如果在sqlplus中运行特定查询,它将返回一个结果java代码和oracle db服务器上的查询结果不同:但没有连接错误,java,oracle,Java,Oracle,我有连接到远程oracle 11g EE db服务器的java代码。如果在sqlplus中运行特定查询,它将返回一个结果 SQL> SELECT COURSENAME from COURSES where skillID=1; COURSENAME -------------------- basic 但是,如果我从下面的java代码运行相同的查询,它不会返回任何结果。我可以在java调试器中将查询语法从查询变量中复制出来,并在oracle上运行它,这样我就知道查询没有语法问题。此外,
SQL> SELECT COURSENAME from COURSES where skillID=1;
COURSENAME
--------------------
basic
但是,如果我从下面的java代码运行相同的查询,它不会返回任何结果。我可以在java调试器中将查询语法从查询变量中复制出来,并在oracle上运行它,这样我就知道查询没有语法问题。此外,它不是SQL异常或类not found异常,因此它似乎成功地运行了查询—只返回零结果
可能发生了什么
private String getCourseForSkill(int skillID){
try{
Class.forName("oracle.jdbc.OracleDriver");
String query="SELECT COURSENAME from COURSES where skillID=" + skillID ;
con = DriverManager.getConnection(url, user, password);
Statement stmt = con.createStatement();
rs = stmt.executeQuery(query);
rs.next();
return rs.getString("COURSENAME");
}
catch (ClassNotFoundException ex){
System.out.println(ex.getMessage());
}
catch (SQLException ex) {
System.out.println(ex.getMessage());
}
return null;
}
我认为您连接到的是不同的Oracle实例,或者更可能是这两种情况下的不同Oracle用户
@灰胡子怪这个URL看起来像jdbc:oracle:thin:@website:port:orcl我通过ssh@website,验证并运行命令=sqlplus 运行sqlplus/@更安全,因为您可以显式指定oracle实例ID。在您的情况下,您的程序似乎正在使用jdbc连接jdbc:oracle:thin:@website:port:orcl,因此您的orainstancename将为“orcl”-只需确保tnsnames.ora文件中的实例“orcl”与jdbc连接使用的“port”相同 如何调试多一点 运行以下代码:
con = DriverManager.getConnection(url, user, password);
con.setAutoCommit(false);
String insert="INSERT INTO COURSES (SKILLID, COURSE)"+ // can add other columns
"values (?, ?) );" // add ? for other columns
PreparedStatement ps = con.createPreparedStatement();
ps.setInt(1, 999);
ps.setString(2, "Complete Bullwarks");
// can set other columns
ps.executeUpdate(insert);
con.commit();
现在手动连接,重新运行原始select语句&查看添加的行是否存在。如果java中没有错误,Oracle中没有新行:极有可能您正在使用两个不同的Oracle实例/模式
也可以重新运行原始的java select代码,但是使用SkillID=999,它很可能会工作
干杯我必须做一个提交来添加行。当我输入commit时;然后远程jdbc连接可以“看到”行。我已经习惯使用SQL server,在使用linq to SQL或SQL management studio时,您不必显式地执行这些类型的提交 可能有三个问题 Java代码中的1 skillID 1。添加调试和检查 2a您正在连接到另一个数据库 2b您正在连接到同一个数据库,但正在从另一个架构中的表中进行选择 要检查2a和2b: 从双用户中选择用户;-连接用户名 从v$数据库中选择名称;-数据库名称 从v$instance中选择主机名;-主机名数据库正在上运行 此查询将所有三个结果返回为一个结果 选择用户| | | | d.name | | | | i.host|u name
来自v$database d,v$instance i 假设您实际连接到同一个数据库,这是由于没有在sql*plus连接中提交插入导致的 通过sql*plus用于连接的OCI进行连接时,Oracle默认情况下不会以自动提交模式运行。任何插入。。。在提交之前,在sql*plus中执行的操作对任何其他会话都不可见。这是因为Oracle默认提供了隔离级别。跨会话的其他用户唯一可见的是写锁 无论您是通过JDBC还是OCI连接第二个连接,在您提交第一个连接之前都不会看到更改 要对此进行测试,请尝试打开2个sql*plus连接并运行以下操作:
-- Executing DDL in Oracle causes an implicit commit before and after the
-- command so the second connection will see the existence of this table:
CREATE TABLE foobar ( x VARCHAR(1) );
在连接1中执行此操作-您应该得到零我们尚未插入任何内容:
SELECT COUNT(*) FROM foobar;
SELECT COUNT(*) FROM foobar;
在连接2中执行此操作:
INSERT INTO foobar ( x ) VALUES ( 'A' );
COMMIT;
在连接1中执行此操作-您仍应获得零插入未提交,因此连接1无法看到它:
在连接2中执行此操作:
INSERT INTO foobar ( x ) VALUES ( 'A' );
COMMIT;
在连接1中执行此操作-您应该得到1它现在已提交:
SELECT COUNT(*) FROM foobar;
您是否尝试调试此方法调用中传递给knowledgeAreaName的内容?尝试记录该值以查看传递给此方法调用的内容。您的程序是否没有抛出ClassNotFoundException,因为根据我的说法,在class.forName中,您应该使用oracle.jdbc.driver.OracleDriver,而不是oracle.jdbc.OracleDriver.From is plug in department-您确定连接url指向与手动查询相同的数据库吗?除了您询问的问题之外,您还可能泄漏了数据库连接和语句对象。另外,在这个实例中可能还可以,但不要养成连接字符串以构建sql语句的习惯。查找“sql注入”以了解原因。@greybearedgeek该URL看起来像jdbc:oracle:thin:@website:port:orcl我通过执行ssh@website,验证并运行command=sqlplusHypothesis:不久前,您使用错误的用户(如系统或某些默认/调试帐户)连接到数据库,并创建了courses表。之后,您作为正确的用户连接并创建相同的表,并用数据填充它。现在,通过ssh手动连接时,您选择了新的良好帐户,但在某些地方运行程序时,存储了错误/默认帐户,并且您的查询针对错误用户拥有的空表运行。请检查一下…Honestl y、 我严重怀疑您不必在SQL server中提交。您正在使用的工具可能会在默认情况下提交或将事务级别设置为“读取未提交”,请参阅