最近写代码的过程中,碰到一些问题,记录一下。

问题1 按照空格分割字符串的需求

需要按照空格进行字符串分割,对其中的数组成员进行处理,分割这个操作,如果按照如下的形式解析,实际上是存在漏洞的,因为如果字符串的格式很规整,各成员之间就是按照1个空格排列的,这种操作可以,如果成员之间的空格个数不同,就很可能分割出错误,

String [] str = line.split(" ");
for(String t : star){
    System.out.println(t);
}

正确的做法,应该是使用正则,无论多少个空格,都可以正确识别,

String [] str = line.split("\\s+");
for(String t : str){
    System.out.println(t);
}

问题2 MyBatis错误

Invalid bound statement (not found): com.dao.XXXDao.updateTableStatus 一般是指Mapper.xml的namespace不对,或者id和Mapper中定义的方法名不一样,或者parameterType对应不上,我这次碰到的原因是Mapper定义的是XXXDao,但实际代码中,用的是XXXZZZDao,两者不同,

因此碰到这类的问题,可以从配置文件开始找具体的原因,大小写等这些极易引起错误的地方是重中之重。

问题3 JDBC错误

如下测试代码,提供了三个参数,

String sql = "select dbms_metadata.get_ddl(?, ?, ?) as dblink from dual";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, "DB_LINK");
ps.setString(2, "PUB_LNK_TEST");
ps.setString(3, "PUBLIC");
ResultSet rs = ps.executeQuery(sql);

执行的时候,提示这个错误,

java.sql.SQLException: ORA-03115: 不支持的网络数据类型或表示法

原因就是当使用PreparedStatement时是不需要在executeQuery中带参数的,改为如下即可,

String sql = "select dbms_metadata.get_ddl(?, ?, ?) as dblink from dual";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, "DB_LINK");
ps.setString(2, "PUB_LNK_TEST");
ps.setString(3, "PUBLIC");
ResultSet rs = ps.executeQuery();

问题4 JDBC连接串中使用SID和SERVICE NAME的不同

在程序中配置JDBC连接串的时候,提示这个错误,

ORA-12505, TNS:listener does not currently know of SID given in connect descriptor

针对这个场景,一种可能就是JDBC连接串中配置的SID或SERVICE NAME不对,我们知道Oracle中的SID用来标识一个数据库实例,而且是一一对应,但是一个数据库可以有多个SERVICE NAME,SID和SERVICE NAME之间没有直接的关系,但往往创建数据库的时候(尤其是单机)会定义SID和SERVICE NAME为相同的名称。

JDBC连接串如果用SID,格式应该如下,通过":"表示,

jdbc:oracle:thin:@<host>:<port>:<SID> 
例如,jdbc:oracle:thin:@192.168.1.1:1521:orcl

JDBC连接串如果用SERVICE NAME,格式应该如下,通过"/"表示,

jdbc:oracle:thin:@//<host>:<port>/<service_name> 
例如,jdbc:oracle:thin:@//192.168.1.1:1521/orcl

因此,如果Oracle数据库中SID和SERVICE NAME是相同的,用如上两种形式,其实都碰巧可以,一旦两者不同,如果用错了格式,就会出现报错,所以了解SID和SERVICE NAME在JDBC连接串中不同的格式,才是避免错误的关键所在。

问题5 SQL Server的CTAS

我们知道在Oracle中可以通过CTAS快速复制一张表,语法格式如下,

CREATE TABLE XXX AS SELECT * FROM ZZZ

但是在SQL Server中,用如上的语法,是会提示错误的,正确的使用是,

SELECT * INTO ZZZ FROM XXX;