WizardWu 编程网

一位台湾的程序员,研究 OOD、.NET 平台在企业信息化之应用、WCF & 工作流、性能调优、数据库。

博客园 首页 新随笔 联系 订阅 管理
  87 Posts :: 0 Stories :: 999 Comments :: 35 Trackbacks

一些 ASP.NET + Oracle 11g 系统边写边学的随笔,包括 Oracle 的「批次更新」,以及将 Oracle 内部编码设定为 Unicode 字符集。


(四) Oracle 的「批次 (batch) 更新」、「批次新增」、「批次删除」语法

Oracle 仍可如 SQL Server、Sybase 数据库,用「分号 (;)」隔离多个 SQL statement,只是 Oracle 前后要再加上 begin、end 关键词,例如:

string strSql = "begin insert into table01(id,name) values(99,'test'); insert into table01(id,name) values(99,'test'); end;";
string strSql = "begin update table01 set name='test2' where id=99; update table01 set name='test2' where id=99; end;";
string strSql = "begin delete from table01 where id=99; delete from table01 where id=19; end;";

因 Oracle 语法较严谨,不能直接在 SQL 语句中,出现「;」等特殊符号。


(五) 让 Oracle 支持 Unicode 处理

Oracle 11g 刚装好时,预设的字符集,会无法处理他国语言的文字。若您在 SqlPlus 输入指令:
SELECT parameter, value FROM v$nls_parameters WHERE parameter LIKE '%CHARACTERSET';

会看到以下的 NLS_LANG 信息:
--------------
NLS_CHARACTERSET
ZHT16MSWIN950 (繁体中文) 或
ZHS16GBK (简体中文)

NLS_NCHAR_CHARACTERSET
AL16UTF16
--------------

接下来,我们要透过「ALTER DATABASE CHARACTER SET」这个指令,去更改 Oracle 内部的字符集编码方式。

请先在 sqlplus 程序中,用 sysdba 角色进入,指令如下:

connect sys/密码 as sysdba;

接着再输入下列指令,执行完后即会自动执行转换的工作:

shutdown immediate;
STARTUP MOUNT;
ALTER SESSION SET SQL_TRACE=TRUE;
ALTER SYSTEM ENABLE RESTRICTED SESSION;
ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;
ALTER SYSTEM SET AQ_TM_PROCESSES=0;
ALTER DATABASE OPEN;
ALTER DATABASE character set INTERNAL_USE AL32UTF8;
ALTER SESSION SET SQL_TRACE=FALSE;
shutdown immediate;
startup;

这种方式可能会造成 Oracle 内,既有的存储数据错乱和遗失,在执行上述指令前,最好要先做备份数据的工作。

接下来,再执行一次下列指令,察看 NLS_LANG 信息:
SELECT parameter, value FROM v$nls_parameters WHERE parameter LIKE '%CHARACTERSET';

NLS_LANG 信息已经变成:
--------------
NLS_CHARACTERSET
AL32UTF8

NLS_NCHAR_CHARACTERSET
AL16UTF16
--------------


此外,网络上广为流传的用这种方法是不正确的:
update props$ set value$='AL32UTF8' where name='NLS_CHARACTERSET';
透过前述正确的「ALTER DATABASE CHARACTER SET」指令,去更改 characterset 后,Oracle 至少会更改 12 张 data dictionary;但若透过这种直接更新 props$ 表的方式,则只完成了其中十二分之一的工作,其潜在的完整性及隐忧可想而知。


若我们要用 ASP.NET 应用程序去撷取、写入 Oracle 时,若有日文字、他国文字时,除了要先如上述把 Oracle 内部的字符集改成 Unicode 外,
在 ADO.NET 的联机方式也要注意。以 Visual Studio 2005 来说,其内建的 OleDb Data Provider 用来联机 Oracle 11g 时,并无法正确处理 Unicode 中的特殊字符和他国文字,甚至在写入 Oracle 时,会出现以下错误:

因为正负号不符合或数据溢位之外的原因,无法转换命令 parameter[1]'' 资料值。 id: 0

解决方式,是改用 OracleClient Data Provider,或用 Oracle 官方的 OleDb Data Provider,下载点为:
http://www.oracle.com/technology/software/tech/windows/ole_db/index.html
http://www.oracle.com/technology/software/tech/windows/odpnet/index.html


=================
参考文件:
http://www.monster.com.tw/archives/471
http://www.javaworld.com.tw/jute/post/view?bid=21&id=137350&sty=1&tpg=2&age=0
http://blog.roodo.com/mywork/archives/6198547.html

=================

posted on 2008-11-27 13:09 WizardWu 阅读(1768) 评论(7) 编辑 收藏

Feedback

#1楼 2010-05-21 11:21 da胖小子      
写的挺好! 我还有一个事情要请教!如果我吧全部要执行的语句全部以 分号(;)的形式隔开,传递给数据库,在执行的过程中是不是有一个语句报错,在这错误之前的语句是不是都不会执行。还有就是如果用这样的方式写的话,是不是就可以不用 Transaction 来写语句了呀?
 回复 引用 查看   

#2楼 2010-05-21 11:26 da胖小子      
还有如果拼接的语句过长怎么办?
 回复 引用 查看   

#3楼[楼主] 2010-05-23 03:35 WizardWu      
我做项目已一年多未用 Oracle 了,以下仅为我的猜测 :

(1) 应也要用事务,才能全部不会执行 (纯猜测)。

(2) 以 SQL Server 为例,我曾用「分号」拼过很长的多个 T-SQL 语句。但问题不是出在语句过长过多,而是 SQL Server 默认有 Parameter 参数数量的限制。SQL Server 好像上限为 2000 个。如此一来,只能自己用写 ADO.NET 做判断,当 Parameter 参数可能会超过 2000 个时,就创建第二个、第三个 SqlCommand 对象。

Oracle 的话,我就不知道了,要劳烦您自行测试或查搜寻引擎了。

 回复 引用 查看   

#4楼 2010-05-24 08:42 da胖小子      
谢谢你的帮助!让我又学到了很多!
 回复 引用 查看   

#5楼[楼主] 2010-05-24 23:43 WizardWu      
you're welcome
 回复 引用 查看   

#6楼 2011-06-28 10:17 四海清一      
ee
 回复 引用 查看   

#7楼 2012-02-08 11:30 ホ-ā、乖‖      
我怎么记得oracle事务没有“开始事务处理”语句。
eg:insert into table1(name)values('1');
insert into table1(name)values('2');
commit;
怎么还要写begin,end??

 回复 引用 查看