确保你的服务器上已经安装了PHP,并且PHP能够连接Oracle和MySQL数据库,对于Oracle,需要安装Oracle客户端库,并在PHP中启用oci8扩展,对于MySQL,PHP通常自带mysqli或PDO扩展,如果不确定,可以查看PHP配置文件或询问服务器管理员。
我们开始具体操作,第一步是连接Oracle数据库,在PHP中,可以使用oci_connect函数来连接Oracle,你需要知道Oracle数据库的地址、端口、服务名,以及用户名和密码,假设Oracle数据库地址是"localhost",服务名是"ORCL",用户是"scott",密码是"tiger",连接代码示例如下:
PHP
<?php
$oracle_conn = oci_connect('scott', 'tiger', 'localhost/ORCL');
if (!$oracle_conn) {
$error = oci_error();
die('连接Oracle数据库失败: ' . $error['message']);
}
echo '成功连接到Oracle数据库';
?>
这段代码尝试连接Oracle数据库,如果失败,会显示错误信息并停止脚本,根据PHP官方文档,oci_connect函数用于建立到Oracle数据库的连接。
第二步是连接MySQL数据库,类似地,使用mysqli扩展来连接MySQL,假设MySQL数据库地址是"localhost",用户是"root",密码是"password",数据库名是"test",连接代码示例如下:

PHP
<?php
$mysql_conn = new mysqli('localhost', 'root', 'password', 'test');
if ($mysql_conn->connect_error) {
die('连接MySQL数据库失败: ' . $mysql_conn->connect_error);
}
echo '成功连接到MySQL数据库';
?>
这里使用了mysqli对象来连接,如果连接出错,也会停止脚本,根据MySQL官方文档,mysqli是PHP中用于操作MySQL的扩展。
第三步是从Oracle读取数据,假设要迁移一个叫做"employees"的表,在Oracle中查询这个表的所有数据,使用OCI函数执行SQL查询。
PHP
<?php
$query = 'SELECT * FROM employees';
$stmt = oci_parse($oracle_conn, $query);
oci_execute($stmt);
$data = array();
while ($row = oci_fetch_array($stmt, OCI_ASSOC)) {
$data[] = $row;
}
?>
这段代码执行查询,并将每一行数据存入数组,OCI_ASSOC表示以关联数组的形式返回数据,这样可以用列名来访问数据,根据Oracle PHP扩展文档,oci_fetch_array函数用于从结果集中获取行。
第四步是将数据插入MySQL,在MySQL中,需要先创建相同的表结构,或者确保表已经存在,这里假设MySQL中已经有一个结构相同的"employees"表,遍历从Oracle获取的数据,逐条插入MySQL,示例如下:

PHP
<?php
foreach ($data as $row) {
$id = $row['ID'];
$name = $row['NAME'];
$salary = $row['SALARY'];
$sql = "INSERT INTO employees (id, name, salary) VALUES ('$id', '$name', '$salary')";
if ($mysql_conn->query($sql) === TRUE) {
echo "记录插入成功: $id<br>";
} else {
echo "错误: " . $sql . "<br>" . $mysql_conn->error;
}
}
?>
这里,使用foreach循环遍历数据,并为每一行构建INSERT语句,然后执行它,注意,直接拼接字符串可能存在SQL注入风险,但在示范中为简单起见先这样写,实际应用中,建议使用预处理语句。
第五步是处理迁移中的问题,数据迁移时,可能会遇到数据类型不匹配的问题,Oracle中的日期类型可能和MySQL中的不同,这时候,可能需要在查询时转换数据类型,或者在插入时进行调整,如果数据量很大,一次性读取所有数据可能会占用太多内存,可以改进代码,分批读取和插入,使用分页查询从Oracle读取数据:
PHP
<?php
$limit = 1000;
$offset = 0;
while (true) {
$query = "SELECT * FROM employees OFFSET $offset ROWS FETCH NEXT $limit ROWS ONLY";
$stmt = oci_parse($oracle_conn, $query);
oci_execute($stmt);
$hasData = false;
while ($row = oci_fetch_array($stmt, OCI_ASSOC)) {
$hasData = true;
$id = $row['ID'];
$name = $row['NAME'];
$salary = $row['SALARY'];
$sql = "INSERT INTO employees (id, name, salary) VALUES ('$id', '$name', '$salary')";
$mysql_conn->query($sql);
}
if (!$hasData) {
break;
}
$offset += $limit;
}
?>
这段代码每次从Oracle读取1000条数据,插入MySQL,直到所有数据都迁移完毕,这样可以减少内存使用,根据数据库查询优化建议,分页查询常用于处理大数据集。
第六步是关闭数据库连接,迁移完成后,记得关闭连接,释放资源,示例如下:
PHP
<?php
oci_free_statement($stmt);
oci_close($oracle_conn);
$mysql_conn->close();
?>
完整的PHP脚本可能包括错误处理和日志记录,可以在迁移过程中记录成功和失败的记录数,以便排查问题,根据实际应用经验,建议在脚本开始时检查表结构是否一致,避免数据插入失败。
如果Oracle和MySQL的表结构不同,可能需要在查询时使用SQL语句进行转换,如果Oracle中的列名是大写,而MySQL中是 lowercase,可以在查询时使用别名,或者,如果数据类型不一致,如Oracle的NUMBER类型对应MySQL的INT或DECIMAL,需要在插入时进行类型转换。
另一个常见问题是字符编码,确保Oracle和MySQL数据库使用相同的字符集,如UTF-8,以避免乱码,可以在连接数据库时设置编码,例如在MySQL连接后执行"SET NAMES utf8"。
这个示范过程涵盖了从连接数据库、读取数据、插入数据到处理大数据的步骤,根据网络资源如PHP社区教程,数据迁移时还可以使用事务来确保数据一致性,但为了简单起见,这里未涉及,如果迁移过程中断,可能需要手动清理部分数据,因此建议先在测试环境运行。
通过以上步骤,你可以用PHP将Oracle数据搬到MySQL,关键是根据实际情况调整代码,并做好错误处理,如果有更多复杂需求,如迁移存储过程或触发器,可能需要额外步骤,但基本的数据表示例应该足够入门。