最近有个项目,要改用达梦数据库,记录一下操作步骤,供大家参考
1,安装达梦数据库
这个直接到达梦数据库官网下载,开发者注册一下,免费下载学习用,商用的自己购买版权。
根据提示安装,这里用WIN7测试的。安全完后打开,创建数据库,一切顺利。操作与mssql或mysql差不多。
2,迁移数据
将MySQL数据迁移进达梦,达梦软件自带了迁移工具,支持各数数据的迁移;
期间遇到各种问题:
1,直连腾讯云数据库做迁移,能链接上,但是迁数据时报错,显示表分析出错,预览时能查看数据,执行时报错,不知是什么原因。然后更换方法2
2,把腾讯云mysql数据导出为sql文件,然后用迁移工具导入,又报错,应该是数据格式不兼容的问题,然后换方法3
3,在本地再搭了个mysql数据库,通过sql文件导入数据,然后再用迁移工具连本地数据库做迁移,成功。这里建议用root用户,之前尝试新建用户去执行竟然连接不上本地mysql数据库。
3,本地PHP环境加达梦驱动
本地win7安装phpStudy测试;
达梦数据库安装目录里面提供了文件 pdo73nts_dm.dll
php73nts_dm.dll(根据自己的php版本选择)
复制到php扩展目录ext下
用编辑工具打开php.ini
php.ini中在末尾添加
extension=pdo73nts_dm
extension=php73nts_dm
重启Apache服务,运行 php -m ,测试dm数据库驱动加载成功
如果加载失败报“PHP Fatal error: Unable to start DM module in Unknown on line 0
”,
则将将达梦数据库安装目录bin下的以下dll文件拷贝至C:\Windows\SysWOW64
和C:\Windows\System32
,重新启动Apache。
phpinfo里面可以看到下图则表示成功
4,PHP链接数据库是否成功
以下代码网上复制的。参考
date_default_timezone_set("Asia/Shanghai");header("Content-type:text/html; Charset=utf-8"); $dm_conf = array( 'host'=> '127.0.0.1:5236', //连接地址及端口 'db'=> 'DBNAME', //数据库名 'db_user' => 'SYSDBA', //用户名 'db_pwd'=> '123456789', //密码); $pdo = new PDO("dm:host=".$dm_conf['host']."; dbname=".$dm_conf['db']."",$dm_conf['db_user'],$dm_conf['db_pwd'] );
输入的中文数据是乱码,则在这里C:\windows\System32\dm_svc.conf
打开加一行
CHAR_CODE=(PG_UTF8)
5,thinkphp框架改造
1,增加DM数据库驱动类,让tp支持达梦数据库,
在目录下\ThinkPHP\Library\Think\Db\Driver增加Dm.class.php文件
复制以下内容并保存
<?php namespace Think\Db\Driver; use Think\Db; defined('THINK_PATH') or exit(); /** * DM数据库驱动类 */ class Dm extends Db{ /** * 架构函数 读取数据库配置信息 * @access public * @param array $config 数据库配置数组 */ public function __construct($config=''){ if ( !extension_loaded('dm') ) { E(L('_NOT_SUPPERT_').':dm'); } if(!empty($config)) { $this->config = $config; if(empty($this->config['params'])) { $this->config['params'] = ''; } } } /** * 连接数据库方法 * @access public * @throws ThinkExecption */ public function connect($config='',$linkNum=0) { if ( !isset($this->linkID[$linkNum]) ) { // $link = dm_connect("localhost", "SYSDBA", "lisonglin1221"); // if(!$link){ echo dm_error().':'.dm_errormsg();exit(); } // dm_setoption($link,1,12345,1); //设置 dm 连接和语句的相关属性,设置UTF8 if(empty($config)) $config = $this->config; $pconnect = !empty($config['params']['persist'])? $config['params']['persist']:$this->pconnect; // $conn = $pconnect ? 'oci_pconnect':'oci_new_connect'; // $this->linkID[$linkNum] = $conn($config['username'], $config['password'],$config['database']);//modify by wyfeng at 2008.12.19 $this->linkID[$linkNum] = dm_connect($config['hostname'],$config['username'], $config['password']); if (!$this->linkID[$linkNum]){ $this->error(false); }else{ dm_setoption($this->linkID[$linkNum],1,12345,1); } // 标记连接成功 $this->connected = true; //注销数据库安全信息 if(1 != C('DB_DEPLOY_TYPE')) unset($this->config); } return $this->linkID[$linkNum]; } /** * 释放查询结果 * @access public */ public function free() { // mysql_free_result($this->queryID); dm_free_result($this->queryID); $this->queryID = null; } /** * 执行查询 返回数据集 * @access public * @param string $str sql指令 * @return mixed */ public function query($str) { if(0===stripos($str, 'call')){ // 存储过程查询支持 $this->close(); $this->connected = false; } $this->initConnect(false); if ( !$this->_linkID ) return false; $this->queryStr = $str; //释放前次的查询结果 if ( $this->queryID ) { $this->free(); } N('db_query',1); // 记录开始执行时间 G('queryStartTime'); $this->queryID = dm_exec($this->_linkID,$str); //dm_exec($link,$sql); $this->debug(); if ( false === $this->queryID ) { $this->error(); return false; } else { $this->numRows = dm_num_rows($this->queryID); return $this->getAll(); } } /** * 执行语句 * @access public * @param string $str sql指令 * @return integer|false */ public function execute($str) { $this->initConnect(true); if ( !$this->_linkID ) return false; $this->queryStr = $str; //释放前次的查询结果 if ( $this->queryID ) { $this->free(); } N('db_write',1); // 记录开始执行时间 G('queryStartTime'); $result = dm_exec($this->_linkID,$str) ; $this->debug(); if ( false === $result) { $this->error(); return false; } else { // $this->numRows = mysql_affected_rows($this->_linkID); // $this->lastInsID = mysql_insert_id($this->_linkID); // return $this->numRows; } } /** * 启动事务 * @access public * @return void */ public function startTrans() { $this->initConnect(true); if ( !$this->_linkID ) return false; //数据rollback 支持 if ($this->transTimes == 0) { mysql_query('START TRANSACTION', $this->_linkID); } $this->transTimes++; return ; } /** * 用于非自动提交状态下面的查询提交 * @access public * @return boolen */ public function commit() { if ($this->transTimes > 0) { $result = mysql_query('COMMIT', $this->_linkID); $this->transTimes = 0; if(!$result){ $this->error(); return false; } } return true; } /** * 事务回滚 * @access public * @return boolen */ public function rollback() { if ($this->transTimes > 0) { $result = mysql_query('ROLLBACK', $this->_linkID); $this->transTimes = 0; if(!$result){ $this->error(); return false; } } return true; } /** * 获得所有的查询数据 * @access private * @return array */ private function getAll() { //返回数据集 $result = array(); if($this->numRows >0) { // while($row = mysql_fetch_assoc($this->queryID)){ while($row = dm_fetch_array($this->queryID)){ $result[] = $row; } // mysql_data_seek($this->queryID,0); // dm_data_seek($this->queryID,0); } return $result; } /** * 取得数据表的字段信息 * @access public * @return array */ public function getFields($tableName) { $result = $this->query('SHOW COLUMNS FROM '.$this->parseKey($tableName)); $info = array(); if($result) { foreach ($result as $key => $val) { $info[$val['Field']] = array( 'name' => $val['Field'], 'type' => $val['Type'], 'notnull' => (bool) (strtoupper($val['Null']) === 'NO'), // not null is empty, null is yes 'default' => $val['Default'], 'primary' => (strtolower($val['Key']) == 'pri'), 'autoinc' => (strtolower($val['Extra']) == 'auto_increment'), ); } } return $info; } /** * 取得数据库的表信息 * @access public * @return array */ public function getTables($dbName='') { if(!empty($dbName)) { $sql = 'SHOW TABLES FROM '.$dbName; }else{ $sql = 'SHOW TABLES '; } $result = $this->query($sql); $info = array(); foreach ($result as $key => $val) { $info[$key] = current($val); } return $info; } /** * 替换记录 * @access public * @param mixed $data 数据 * @param array $options 参数表达式 * @return false | integer */ public function replace($data,$options=array()) { foreach ($data as $key=>$val){ $value = $this->parseValue($val); if(is_scalar($value)) { // 过滤非标量数据 $values[] = $value; $fields[] = $this->parseKey($key); } } $sql = 'REPLACE INTO '.$this->parseTable($options['table']).' ('.implode(',', $fields).') VALUES ('.implode(',', $values).')'; return $this->execute($sql); } /** * 插入记录 * @access public * @param mixed $datas 数据 * @param array $options 参数表达式 * @param boolean $replace 是否replace * @return false | integer */ public function insertAll($datas,$options=array(),$replace=false) { if(!is_array($datas[0])) return false; $fields = array_keys($datas[0]); array_walk($fields, array($this, 'parseKey')); $values = array(); foreach ($datas as $data){ $value = array(); foreach ($data as $key=>$val){ $val = $this->parseValue($val); if(is_scalar($val)) { // 过滤非标量数据 $value[] = $val; } } $values[] = '('.implode(',', $value).')'; } $sql = ($replace?'REPLACE':'INSERT').' INTO '.$this->parseTable($options['table']).' ('.implode(',', $fields).') VALUES '.implode(',',$values); return $this->execute($sql); } /** * 关闭数据库 * @access public * @return void */ public function close() { if ($this->_linkID){ dm_close($this->_linkID); } $this->_linkID = null; } /** * 数据库错误信息 * 并显示当前的SQL语句 * @access public * @return string */ public function error() { $this->error = dm_error().':'.dm_errormsg();; if('' != $this->queryStr){ $this->error .= "\n [ SQL语句 ] : ".$this->queryStr; } trace($this->error,'','ERR'); return $this->error; } /** * SQL指令安全过滤 * @access public * @param string $str SQL字符串 * @return string */ public function escapeString($str) { if($this->_linkID) { return mysql_real_escape_string($str,$this->_linkID); }else{ return mysql_escape_string($str); } } /** * 字段和表名处理添加` * @access protected * @param string $key * @return string */ protected function parseKey(&$key) { $key = trim($key); if(!is_numeric($key) && !preg_match('/[,\'\"\*\(\)`.\s]/',$key)) { $key = '`'.$key.'`'; } return $key; } }
以上驱动文件是拿mysql的驱动文件来改造的。因时间紧没有全部测试,不一定全对。大家使用时可留意一下。
2,修改数据库连接配置文件为达梦数据库
<?php return array( 'DB_TYPE' => 'Dm', 'DB_HOST' => 'localhost', // 服务器地址 'DB_USER' => 'SYSDBA', // 用户名 'DB_PWD' => '******', // 密码 'DB_PORT' => '5236', // 端口 'DB_NAME' => 'OA', // 数据库名 'DB_PREFIX' => '', // 数据库表前缀 );
然后测试一下,数据查询功能,成功
public function test(){ $m=M('test'); $data=$m->field('ID,NAME')->limit(10,3)->select(); dump($data); echo $m->getLastSql(); }
完善支持THINKPHP3.2的原开发程序。项目不用大改,不过只是测试了查询功能,其它 增、删、改 没空测试,大家自己测试。应该也差不多了