0

我想将我的 MS Access 数据导入 MySQL 数据库。我正在使用xampp. 我编写了获取 Access 表并创建查询字符串的 PHP 代码。当我执行我的程序时,它给了我以下错误:

内存不足(需要 2465528 字节)

我的代码是:

<?php
$conn=odbc_connect('my','','');/* connected */
$sql="SELECT * FROM mytable";
$rs=odbc_exec($conn,$sql);
$sqlstr="";

$tablefields=array("Name","City","State");

$sqlstr="INSERT INTO `mytable`(";

$temp=0;
for($i=0;$i<count($tablefields)-1;$i++)
{

    $sqlstr.="`".$tablefields[$i]."`";
    if($temp==count($tablefields)-2)
    {
    }
    else
    {
        $sqlstr.=",";
        $temp++;
    }

}

$sqlstr.=") VALUES";

//echo $sqlstr;

//return;
$sqlstr.="(";
while($row = odbc_fetch_array($rs)) 
{ 

    $temp=0;
    foreach ($row as $key => $value)
    {
        $sqlstr.="'".$value."'";
        if($temp==count($row)-1)
        {
            $sqlstr.="),(";
        }else
        {
            $sqlstr.=",";
            $temp++;
        }
        //echo $sqlstr;
    }



}    
$sqlstr.=")";

     connection();





$res=mysql_query($sqlstr)or die (mysql_error());




function connection()
{
$host="localhost";
$user="root";
$pass="";
$database="mydatabase";

$cnx=mysql_connect($host, $user, $pass);
mysql_connect($host, $user, $pass);
echo (mysql_error($cnx));

mysql_select_db($database, $cnx);
echo (mysql_error($cnx));

return $cnx;
}
?>

我 确实改变max_execution_time = 3600memory_limit = -1php.inimy.ini

    key_buffer = 200M
    sort_buffer_size = 200M
    read_buffer = 200M
    write_buffer = 200M

谁能告诉我问题出在哪里?

4

2 回答 2

1

对于处于类似情况的任何未来读者,更好的方法是使用准备好的语句来执行 INSERT 操作。优点包括:

  • 您不必猜测一批插入的“正确”尺寸应该是多少。
  • 代码更易于维护和扩展。
  • 如果文本字段包含单引号,它不会爆炸。
  • 它不容易受到 SQL 注入问题的影响。
  • 它能够正确处理 Null 值。
<?php
$tablefields=array("Name","City","State");

$myDb = new PDO('mysql:host=localhost:3307;dbname=myDb', 'root', 'whatever');
$myDb->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$mySt = $myDb->prepare("TRUNCATE TABLE mytable");
$mySt->execute();

$params = array_fill(0, count($tablefields), '?');
$sqlstr = "INSERT INTO mytable (`" . implode("`,`", $tablefields) .
        "`) VALUES (" . implode(",", $params) . ")";
// i.e., INSERT INTO mytable (`Name`,`City`,`State`) VALUES (?,?,?)

$mySt = $myDb->prepare($sqlstr);

$accDb = new PDO('odbc:' .
        'Driver={Microsoft Access Driver (*.mdb, *.accdb)};' .
        'Dbq=C:\\Users\\Public\\Database1.accdb;');
$accDb->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$sqlstr = "SELECT [" . implode("],[", $tablefields) . "] FROM myTable";
// i.e., SELECT [Name],[City],[State] FROM myTable

$accSt = $accDb->prepare($sqlstr);
$accSt->execute();

$rowCount = 0;
while ($row = $accSt->fetch()) {
    for ($i = 0; $i < count($tablefields); $i++) {
        $params[$i] = $row[$tablefields[$i]];
    }
    $mySt->execute($params);
    $rowCount++;
}
echo $rowCount . " row(s) copied.<br />";
于 2013-11-07T12:55:22.870 回答
0

每几百条记录插入一次。像这样的东西: -

<?php
$conn=odbc_connect('my','','');/* connected */
$sql="SELECT * FROM mytable";
$rs=odbc_exec($conn,$sql);
$sqlstr="";

$tablefields=array("Name","City","State");

$sqlhead="INSERT INTO `mytable`(`".implode("`,`", $tablefields)."`) VALUES ";

connection();

$sqlitem = array();
while($row = odbc_fetch_array($rs)) 
{ 
    $temp=0;
    if (count($sqlitem) > 255)
    {
        $res=mysql_query($sqlhead.implode(',', $sqlitem))or die (mysql_error());
        $sqlitem = array();
    }
    $sqlitem[] = "('".implode("','",$row)."')";
}    

if (count($sqlitem) > 0)
{
    $res=mysql_query($sqlhead."(".implode('),(', $sqlitem).")")or die (mysql_error());
}

function connection()
{
    $host="localhost";
    $user="root";
    $pass="";
    $database="mydatabase";

    $cnx=mysql_connect($host, $user, $pass);
    mysql_connect($host, $user, $pass);
    echo (mysql_error($cnx));

    mysql_select_db($database, $cnx);
    echo (mysql_error($cnx));

    return $cnx;
}
?>

您可以通过将插入转移到一个类中(而不仅仅是使用数组)来更干净地做到这一点。传递每一行以插入类,如果当前总数大于 X 则执行插入,并且还从类中的析构函数执行插入。如果您需要进行更多插入,则不必在循环结束时做出决定。

请注意,不推荐使用 mysql_* 函数,您可能应该改用 mysqli_* 函数。

于 2013-11-07T10:56:05.823 回答