【问题标题】:Possible to make this code valid/speed up?可以使此代码有效/加速吗?
【发布时间】:2010-08-23 23:48:37
【问题描述】:

我有一个注册表单,它获取消费者信息,将其存储在会话中,从页面传递到页面,然后在完成后存储在数据库中。最初该表仅列出最多 16 人的字段,但在读取关系数据库后,发现这是愚蠢的。

我已经创建了一个名为“members”和“managers”的表。每个注册都会接受信息输入,将经理 ID 存储在相应的表中,并在包含经理 ID 的每个成员行中放置一个参考字段。

虽然我一次最多允许 16 名成员注册,但范围可以从 1 到 16 名。

我最好的猜测是在注册超过 1 个成员的情况下使用 FOR 循环运行多个 INSERT 语句。

在下面的示例中,我使用变量 $num 来表示单个成员的信息,并使用 $total 来表示正在注册的所有成员的数量。这里的代码不起作用,但正在寻找:

a) 纠正方法

b) 了解是否有更“有效”的方式来执行此类 INSERT

示例代码:

<?php 
    $conn = mysql_connect("localhost", "username", "pw");
    mysql_select_db("db",$conn);

    for ($num=1; $num<=$total; $num++) {

    $sql = "INSERT INTO table VALUES ('', '$clean_f'.$num.'fname', '$clean_f.$num.mi', '$clean_f.$num.lname', '$clean_f.$num.fednum', '$clean_f.$num.dob', '$clean_f.$num.ssn', '$clean_f.$num.address', '$clean_f.$num.city', '$clean_f.$num.state', '$clean_f.$num.zip', '$clean_f.$num.phone', '$clean_f.$num.email')";

    $result = mysql_query($sql, $conn) or die(mysql_error());
    }

    mysql_close($conn);
    header("Location: completed.php");
?>

【问题讨论】:

    标签: php mysql insert for-loop


    【解决方案1】:

    如果您的所有语句在结构上都相同,但参数值不同,请考虑使用支持预准备语句的 PDO 扩展。准备好的语句的好处可以在这里阅读(http://www.php.net/manual/en/pdo.prepared-statements.php),但一般来说,同一个语句只需要编译一次,但可以使用不同的参数执行任意多次,这可以让你的脚本更多“高效”。

    使用 PDO,您的代码可能类似于:

    $db = new PDO('mysql:host=localhost;dbname=db', 'username', 'pw');
    
    $statement = $db->prepare('INSERT INTO tablename (field1, field2, field3, ...) VALUES (?,?,?,?');
    
    for ($num=1; $num<=$total; $num++) {
        $statement->execute(array('val1', 'val2', 'val3', '...'));
    }
    

    【讨论】:

    • @rr - 我将不得不对此进行调查。这正是我需要的,是的,INSERT 语句是相同的。感谢你的分享。我会让你知道我的结果!
    • 这比我的建议更好。如果可以,请使用这个。
    • @rr - 非常感谢您的帮助。注意:我实际上在使用 mysqli 或 PDO 之间有点纠结(实际上是在你的建议中提出的),但很快就会做出决定。再次感谢和很好的回应!
    • 当然,两者非常相似。主要区别在于 PDO 为数据访问提供了一个抽象层(因此数据库驱动程序之间的切换很容易)并且可以说更加“标准化”,但对于小型应用程序来说确实无关紧要。
    • 另外,请参阅stackoverflow.com/questions/13569/… 以了解有关 mysqli 与 PDO 的讨论
    【解决方案2】:

    通常,将查询置于循环中是一件坏事。通常有更好的方法。在这种情况下,您应该使用多插入语法。您的 INSERT 不起作用,因为您没有指定字段。我假设表名和 VALUES 之间缺少空格是一个错字,以及错误的引用。

    INSERT INTO table_name (field1, fname, lname, fednum, ...) 
    VALUES ('val1', 'Pete', 'Moss', 1234), 
    ('val2', 'T.', 'Cupp', 54321), 
    ('val3', 'Youdid', 'Watt', 787123);
    

    【讨论】:

    • 您的代码假定我知道要创建多少插入语句。我不知道 val2,3,4,5,6,7,8+ 会存在。我只知道需要 1 个成员,一次最多可以有 16 个,但这取决于用户。您可以插入任何表格而不用顺便命名字段(虽然我同意这是不好的做法)
    • 然后使用你的 for 循环在VALUES ( 之后构建一个字符串 并在末尾附加另一个) 来限制它。那么你仍然只需要一个查询,你不需要知道有多少。
    • @Andrew - 我想这是我的直接问题。另外 - 只有 () 的 VALUES 表示单个插入。这个想法是有可能使用新信息创建 14 多行,而不是全部在一行中。
    • 我上面给出的示例将创建 3 行。不知道你所说的“一排”是什么意思。不指定字段是极差的做法,因为数据必须按特定顺序排列。
    【解决方案3】:

    如果我没看错的话,解决方案是从固定查询字符串开始:

    $queryString = "INSERT INTO table (field1, field2, ...) VALUES ";
    

    然后运行一个循环来构建可延展的部分。将您的值放入数组中会使事情变得更容易:

    $queryInsert = '';
    $total = count($value1Array);
    while ($i < $total) {
        $queryInsert .= "('$value1Array[$i]','$value2Array[$i]','$value3Array[$i],...), ";
        ++$i;
    }
    

    然后附加到第一个查询片段:

    $queryString = $queryString.$queryInsert;
    

    剪掉尾随的,,你就可以开始了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多