今天运行壹個小程序,功能是读取指定目录下的 SQL 脚本,并加载到内存中批量执行,之前的程序运行良好。但是今天相关开发人员更新了其中壹個 SQL 脚本,于是程序运行的时候就出错了,错误提示信息如下:批处理中出现错误: ORA-01756: 引号内的字符串没有正确结束。用 Notepad++ 打开看了下 SQL 脚本,没有发现明显的语法错误,再仔细找了找包含单引号和双引号的语句,也没有看到语句未正确结束的地方。于是有点困惑,开始启动 Eclipse 的 Debug 模式仔细分析,并调低了日志级别到 DEBUG,将所有解析出来的 SQL 语句打印至控制台。
结果在日志中发现有的 SQL 语句解析之后居然是乱码,截取部分内容如下所示:
1
|
<code class=
"hljs"
>4,2,'?占淇迹罩湛贾?
from
TRUSTDB.TRUST_PRDT_MEM_SET t</code>
|
很明显的,数字2后面的部分只有壹個开始的单引号,而没有关闭的单引号,看来极有可能是这段乱码引起的,上述内容在原始的 SQL 文件(GBK 编码)中实际是这样的:
1
|
<code class=
"hljs javascript"
><span class=
"hljs-number"
>4,<span class=
"hljs-number"
>2,<span class=
"hljs-string"
>
'日间开始,日终开始之前'
<span class=
"hljs-keyword"
>
from
TRUSTDB.TRUST_PRDT_MEM_SET t</span></span></span></span></code>
|
不知道为什么经过 Java 解析之后会变成壹串乱码。找到问题的所在,修改的时候直接把“日间开始,日终开始之前”中间的全角逗号改成了半角逗号,问题就宣告解决,同时我还注意到在这個 SQL 脚本中,还有其它地方也使用到了全角的逗号,但是那些地方没有出问题,独独此处报错了,真是奇怪。在我看来,这個修复方法实在不太理想,不知道是否还有更好的方法。另外,附上我的 SQL 文件解析代码如下。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<code
class
=
"hljs javascript"
>List<<span
class
=
"hljs-built_in"
>String> loadSql(<span
class
=
"hljs-built_in"
>String filepath)
throws
Exception {
List<<span
class
=
"hljs-built_in"
>String> sqls = <span
class
=
"hljs-keyword"
>
new
ArrayList<<span
class
=
"hljs-built_in"
>String>();
StringBuffer sb = <span
class
=
"hljs-keyword"
>
new
StringBuffer();
byte
[] buff = <span
class
=
"hljs-keyword"
>
new
byte
[<span
class
=
"hljs-number"
>
1024
];
int
byteRead = <span
class
=
"hljs-number"
>
0
;
LOGGER.debug(<span
class
=
"hljs-string"
>
"Start parse sql file ["
+ filepath + <span
class
=
"hljs-string"
>
"]."
);
InputStream sqlFileIn = ClasspathResourceLoader.getResourceAsStream(filepath);
<span
class
=
"hljs-comment"
>
//开始读取文件内容
<span
class
=
"hljs-keyword"
>
while
((byteRead = sqlFileIn.read(buff)) != <span
class
=
"hljs-number"
>-
1
) {
sb.append(<span
class
=
"hljs-keyword"
>
new
<span
class
=
"hljs-built_in"
>String(buff, <span
class
=
"hljs-number"
>
0
, byteRead));
}
<span
class
=
"hljs-comment"
>
//将读取到的字符串以换行符分割
<span
class
=
"hljs-built_in"
>String[] sqlArr = sb.toString().split(<span
class
=
"hljs-string"
>
"(;\\s*\\r\\n)|(;\\s*\\n)"
);
<span
class
=
"hljs-keyword"
>
for
(
int
i = <span
class
=
"hljs-number"
>
0
; i < sqlArr.length<span
class
=
"hljs-number"
>-
1
; i++) {
<span
class
=
"hljs-comment"
>
//将每個独立语句中的注释和末尾的分号去掉,只保留语句内容
<span
class
=
"hljs-built_in"
>String sql = sqlArr[i].replaceAll(<span
class
=
"hljs-string"
>
"--.*"
, <span
class
=
"hljs-string"
>
""
).replaceAll(<span
class
=
"hljs-string"
>
";"
, <span
class
=
"hljs-string"
>
" "
).trim();
<span
class
=
"hljs-keyword"
>
if
(!sql.equals(<span
class
=
"hljs-string"
>
""
)) {
sqls.add(sql);
}
}
LOGGER.debug(<span
class
=
"hljs-string"
>
"sql list="
+ sqls);
<span
class
=
"hljs-keyword"
>
return
sqls;
}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
|
目前这個问题暂存,待日后有更好的方法时我会回过头来继续补充完善。其实有個更简单的办法找到 SQL 语句中出错的地方,就是把日志中解析之后输出的 SQL 语句复制粘贴到 PL/SQL Developer 的编辑器中,观察这些语句的语法染色,通常来讲,如果因为单引号或者双引号不匹配引发了语句错误,在编辑器里显示出来的效果就会有点不大壹样。我们只需要从代码尾部开始往上找到那個不壹样的地方,然后修改掉它,就很容易解决问题了。
【推荐】腾讯云新用户域名抢购1元起,抓紧抢购
· 阮一峰:加密货币的本质
· ofo被曝订单较峰值跌六成 账户现金仅能支撑一个月
· 途牛宣布一亿美元股票回购计划及CTO任命
· 我们帮你划了一份微信公开课PRO的重点
· iPhone 4S起死回生,可降级至iOS 6.1.3
» 更多新闻...
· 以操作系统的角度述说线程与进程
· 软件测试转型之路
· 门内门外看招聘
· 大道至简,职场上做人做事做管理
2013-03-08 jquery获取一个table中的一行的每个td的内容