$wpdb->insert - insertar múltiples filas
¿Cómo puedo usar $wpdb->insert
para insertar múltiples filas? Aquí está mi código.
for($i=0; $i<=$urlCount; $i++) {
$stat = $wpdb->insert(
'WP_URLS',
array(
'POSTID' => $post->ID,
'URL' => $_POST['url'.$i]
)
);
}
Este código solo funciona para la primera inserción (es decir, cuando $i = 0
, cuando el valor es url_0
). A veces el conteo de URLs será mayor a 100 y otras veces será cero. Así que en lugar de escribir el código 100 veces, solo quiero tener un bucle simple que funcione para cualquier número de registros. Esa es la razón por la que opté por un bucle.
Gracias por la ayuda.
La estructura de la tabla es
CREATE TABLE WP_URLS (
POSTID BIGINT NOT NULL,
URL VARCHAR(254)
);

Supongo que el problema es bastante simple. No mostraste todo el código, pero creo que el problema es que estás guardando la inserción por alguna razón desconocida como string
en una variable llamada $stat
. Cada vez que llenas la variable con una nueva consulta, estás sobrescribiendo tu variable. Deberías usar $stat .= $wpdb->insert( ...etc... )
en su lugar para concatenar a tu string. No olvides establecer la variable como un string vacío antes del bucle, para que puedas concatenar: $stat = ''
.
Otra forma - en mi opinión mejor - sería usar un array. Razón: Puedes depurar el código más fácilmente. Y por favor lee el comentario en el código.
$stats = array();
for( $i = 0; $i <= $urlCount; $i++ )
{
$stats[] = array(
'POSTID' => $post->ID,
// ¿realmente estás recuperando **TODAS** tus URLs como "url1", "url2", etc.
// a través de algún formulario enviado via $_POST?
'URL' => filter_var(
$_POST["url{$i}"],
FILTER_VALIDATE_URL,
FILTER_FLAG_SCHEME_REQUIRED
)
);
}
foreach ( $stats as $stat )
$wpdb->insert( 'WP_URLS', $stat );

Aunque hay una respuesta aceptada, funciona con consultas separadas para cada inserción.
Esta podría ser una mejor solución para insertar datos en una sola consulta:
<?php
/**
* Un método para insertar múltiples filas en la tabla especificada
*
* Ejemplo de uso:
*
* $insert_arrays = array();
* foreach($assets as $asset) {
*
* $insert_arrays[] = array(
* 'type' => "multiple_row_insert",
* 'status' => 1,
* 'name'=>$asset,
* 'added_date' => current_time( 'mysql' ),
* 'last_update' => current_time( 'mysql' ));
*
* }
*
* wp_insert_rows($insert_arrays);
*
*
* @param array $row_arrays
* @param string $wp_table_name
* @return false|int
*
* @author Ugur Mirza ZEYREK
* @source http://stackoverflow.com/a/12374838/1194797
*/
function wp_insert_rows($row_arrays = array(), $wp_table_name) {
global $wpdb;
$wp_table_name = esc_sql($wp_table_name);
// Configurar arrays para Valores Reales y Marcadores de Posición
$place_holders = [];
$row = implode(', ', array_keys($row_arrays));
$values = array_values($row_arrays);
foreach (array_values($row_arrays) as $key => $param) {
if(is_numeric($param)) {
if($key == 0){
array_push($place_holders, " '%d'");
} else {
array_push($place_holders, ", '%d'");
}
} else {
if($key == 0){
array_push($place_holders, " '%s'");
} else {
array_push($place_holders, ", '%s'");
}
}
}
$params = implode('', $place_holders);
$query = "INSERT INTO {$wp_table_name} (" . $row . ") VALUES (" . $params . ")";
if($wpdb->query($wpdb->prepare($query, $values))){
return true;
} else {
return false;
}
}

Sugeriría cambiar el orden de los argumentos y poner primero el argumento implícitamente requerido: $table_name
. Además, en la mayoría de los casos puedes usar directamente $wpdb->table_name
. Desde el punto de vista de la legibilidad, podrías considerar colocar INSERT INTO {$wp_table_name} (
después del bucle foreach
para que quede claro qué sucede en qué orden (bucle, filas de consulta, construir array VALUES
, luego asignar e insertar. Sobre tus argumentos de prinft
: Hay más que string/int. También podrían haber problemas con filas no predeterminadas y el modo SQL strict
.
