2011-01-07 9 views
14

Podczas rejestracji online, klient może wybrać wiele programów, które zdecydują się zapisać. Programy te są trzycyfrowymi liczbami całkowitymi i są przechowywane w tablicy.Jak wstawić tablicę do pojedynczej instrukcji MySQL Przygotowane w/PHP i PDO

Na przykład:

Chcę zapisać się programid 155, 165, 175, i 185.

Moja tablica jest skonfigurowany tak proste, jak:

$data = array(); 

$data[] = 155; 

$data[] = 165; 

$data[] = 175; 

$data[] = 185; 

Kiedy przychodzi czas aby wstawić tę informację do powiązanej tabeli, uwzględniam również dodatkowe elementy z drugiej części rejestracji:

Na przykład, jeśli robiłem POJEDYNCZĄ paczkę programu Oświadczenie rt będzie wyglądać następująco:

$stmt = $db->prepare("INSERT INTO table SET memberID=?, programID=?, date_added=NOW()"); 
$stmt->execute(array($memberid, 155)); 

I zwykle tworzyć prosty pętli dla tablicy powyżej, które nazywamy wiele instancji SQL i wykonanie takich jak:

for($j = 0; $j < (count($data)-1); $j++) { 
    $stmt = $db->prepare("INSERT INTO table SET memberID=?, programID=?, date_added=NOW()"); 
    $stmt->execute(array($memberid, $data[$j])); 
} 

zrobić uświadomić sobie, że powyższy kod jest nieprawidłowy ($ data [$ j]), ale szuka właściwego sposobu wykonywania połączenia.

Powiedziano mi też wcześniej, że budowanie pojedynczego dynamicznego polecenia sql jest ogólnie lepsze niż wiele połączeń, jak wyżej. Moje pierwsze przejście byłoby coś w rodzaju:

$sql = array(); 
foreach($data as $row) { 
    $sql[] = '("'.$memberid.'", "'.$row[$j].'", NOW()")'; 
} 
mysql_real_query('INSERT INTO table (memberid, programid) VALUES '.implode(',', $sql)); 

ale z PDO nie jestem do końca pewien, jak to działa, szczególnie w przypadku symboli zastępczych (?).

Wszelkie sugestie?

+2

Nie uruchamiaj przygotować więcej niż jeden raz. Jeden jest przygotowany, możesz wykonać go wiele razy z różnymi wartościami. – Powerlord

Odpowiedz

25

Można zbudować kwerendę programowo ...:

$sql = 'INSERT INTO table (memberID, programID) VALUES '; 
$insertQuery = array(); 
$insertData = array(); 
foreach ($data as $row) { 
    $insertQuery[] = '(?, ?)'; 
    $insertData[] = $memberid; 
    $insertData[] = $row; 
} 

if (!empty($insertQuery)) { 
    $sql .= implode(', ', $insertQuery); 
    $stmt = $db->prepare($sql); 
    $stmt->execute($insertData); 
} 
+0

dzięki za sugestię. W tej chwili bawię się z tym. Implozja rzuca błąd, ale dam ci znać, co się pojawi. – JM4

+0

@ JM4: To był drobny błąd z mojej strony. Naprawiłem to powyżej ... – ircmaxell

+0

świetnie. dzięki za pomoc! Zastanawiając się nad tekstem date_added w powyższym przykładzie, utworzenie nowego elementu $ insertdata [] = NOW() nie zostałoby poprawnie wstawione (jako że PDO traktowałoby to jako dane wejściowe varchar i traktowało je dosłownie zamiast formatu daty mysql.Zwykle po prostu generowałbym zapytanie: date_added = NOW(), ale z wartościami jak wyżej, czy można to zrobić? Rozumiem, że mogłem po prostu uruchomić php date (Y-m-d H: i: s), ale chciałem sprawdzić, czy TERAZ() było możliwe. – JM4

0

Co szukasz jest jak zrobić insert luzem, to jest więcej niż SQL związanych z samą PDO.

Trzeba zrobić dokładnie to samo, co przy * _query, zbudować kwerendę wstawiania zbiorczego i macierz parametrów obok siebie.

$placeholder = array(); 
$values = "?, ?, ?, ..."; 
$args = array(); 
foreach ($arrays as $array) { 
    $placeholder[] = $value; 
    $args[] = $array['col1']; 
    $args[] = $array['col2']; 
    $args[] = $array['col3']; 
    ... 
}  
$sql = "INSERT INTO table (col1, col2, ...) VALUES (" 
    . implode('), (', $placeholder) 
    . ")"; 
$stmt = $db->prepare($sql); 
$db->execute($sql, $args); 

Jest to brzydki, ale działający algorytm, jak sądzę.

9

2 rozwiązania

// multiple queries 
$stmt = $pdo->prepare('INSERT INTO table SET memberID=:memberID, programID=:programID, date_added=NOW()'); 
$data = array(155, 165, 175, 185); 
foreach($data as $d) { 
    $stmt->execute(array(':memberID' => $memberid, ':programID' => $d)); 
} 

I

// one query 
$data = array(155, 165, 175, 185); 
$values = array(); 
foreach($data as $d) { 
    $values[] = sprintf('(%d, %d, NOW())', $d, $memberid); 
} 
$sql = sprintf('INSERT INTO table (memberID, programID, date_added) VALUES %s', implode (', ', $values)); 
$pdo->exec($sql); 
+0

dziękuję za twój post, chociaż nie jest pierwszą odpowiedzią powyżej na wielokrotne pytania i opodatkowanie bazy danych bardziej niż drugie? (większość powiedziała mi, żebym nie używał jako taki). Testuję to drugie, ponieważ prawdopodobnie lepiej pasuje do moich potrzeb. Zauważ: mam zero problemów podczas wykonywania wielu zapytań, tylko powiedziano mi, że jest "wolniej" (z maksimum 8 rekordów, jedna sekunda nic dla mnie nie znaczy). – JM4

+0

Wielokrotne zapytania są wolniejsze o dziesięć milisekund, ale są bardziej czytelne i łatwiejsze do debugowania. –

Powiązane problemy