PHP with Oracle Work Tips

这次开发的道具购买系统由于牵涉到用户信息的修改,所以采用了PHP直接调用Oracle数据库的做法 ,到目前为止系统已经在内部测试阶段,所以写一些第一次用PHP操作Oracle数据库的心得。

我的开发环境:

本地机:

OS: Windows NT 5.1 build 2600
PHP:PHP5.1.1
PHP组件:Oci8 Support
Web Server: Apache/2.0.55
Database: Oracle 10.1

测试机:

OS: Linux 2.6.9.5
PHP:PHP 4.4.2
PHP组件:Oci8 Support
Web Server: Apache/2.0.58
Database: Oracle 10.1

开发过程中使用了Pear:DB作为数据库抽象层,下面是一些使用过程中同Mysql不同的部分:

1、连结信息
$dbname_oci = "(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1521)))(CONNECT_DATA=(SID=JIRA)))";
$dsn_oci = "oci8://"."username".":"."password"."@".$dbname_oci;
$dbh_oci = Db::connect($dsn_oci);

可以发现在作数据库连结信息的时候同Mysql数据库还是有较大的区别的。

2、分页
Oracle数据库的SQL语言不支持Limit子句,所以在做分页SQL语句时,要使用ROUNUM以及minus子句实现。例:
"SELECT * FROM iteminfo WHERE typecode='".$typecode."' AND ROWNUM<=".$pager ->offset()."+".$pager ->limit()."
minus
SELECT * FROM iteminfo WHERE typecode='".$typecode."' AND ROWNUM<=".$pager ->offset()."";

3,日期处理
在Mysql中,我习惯将时间用Unix时间戳的格式来存储。在输出过程中使用date函数来制定日期输出格式就行了。但是在Oracle中,日期格式是直接以"YYYY-MM-DD HH:mm:ss"的格式来存放的,这样在插入数据,编辑数据(特别是日期累加)的过程中,就需要用另外一种方式处理了。在Oracle数据库的SQL语句中,取得当前时间的SQL是这样的,例:
"SELECT sysdate FROM dual";
但是这样取到的数据可能并不是你希望获取的日期格式,那么就要用到SQL中的to_char函数了,例:
"SELECT TO_CHAR(sysdate, 'DD-MM-YY HH24:MI:SS') FROM dual";
具体的输出格式规范,可以在Google中查找to_char获取;
在日期处理过程中,发现过通过to_char输出的时间,不能够插入到日期格式的数据表中,在插入的过程中,只能将通过to_char获取的时间字符串再用to_date函数返还后,才能正确插入数据表中,就这个问题就折磨了我很长时间。

4,编码处理
这个问题发生于服务器的差异,在本地可以正常显示的中文字符在测试机中显示均为“???”,
猜测问题可能是PHP的字符设置问题,也许是Apache的字符设置问题,也可能是服务器安装 了Oci8扩展后的客户端数据库字符设置的问题,在修改php.ini和httpd.conf文件无结后,终于确定问题出现在Oci8扩展的客户端数据库 字符设置上,运行以下命令后,页面上的中文字符正常显示,问题解决!
export NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK

重启Apache

5,自增长ID处理
Mysql数据库中,只需在建表中将ID字段设置为automatic_increment时,在INSERT的语句中,只要放入null,就可以实现ID自动增长的需要,但是在Oracle中,这种类型不被支持。所以只能通过设置一个叫做ID.Nextval的值来实现这个目的。

1 comment:

Anonymous said...

nice page...