Foros del Web » Programando para Internet » PHP »

doble auto_increment

Estas en el tema de doble auto_increment en el foro de PHP en Foros del Web. Hola a todos y espero que puedan ayudarme y orientarme. Se trata de lo siguiente, he creado una tabla para guardar las categorias de productos ...
  #1 (permalink)  
Antiguo 16/03/2005, 14:38
 
Fecha de Ingreso: noviembre-2002
Mensajes: 59
Antigüedad: 15 años
Puntos: 0
doble auto_increment

Hola a todos y espero que puedan ayudarme y orientarme. Se trata de lo siguiente, he creado una tabla para guardar las categorias de productos y por ahora todo va bien, mi problema surge cuando quiero ordenar los registros (categorías) conforme a un orden determinado, evidentemente no puedo cambiar el "id auto_increment" al que va asociado cada categoría ya que es el valor de referencia que tomará el producto que pertenece a ese grupo determinado (para que si se edita la categoría los productos sigan perteneciendo a la misma categoría), y tampoco puedo crear un segundo campo auto_increment en la misma tabla del primero ya que no está permitido.
He utilizado el comando count(*) para que me cuente el número de filas y tomar el valor de referencia + 1, y situarlo en otro campo de la tabbla llamado "posicion", pero claro eso puede suponer que dos filas puedan tener el mismo valor si borro uno o varios registros. Finalmente he optado por un select con 20 valores (ya que en principio tiene porque haber más) pero me parece una solución un poco cutre, además de que repite el problema anterior.

Mi pregunta es ¿Cómo puedo simular ese segundo auto_increment?


Nota: he utilizado el buscador y revisado las faqs, pero no he visto nada parecido o se me ha pasado.

Espero haberme sabido explicar. Gracias anticipadas Jonai

Última edición por jonai; 16/03/2005 a las 14:43
  #2 (permalink)  
Antiguo 16/03/2005, 14:55
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 15 años, 11 meses
Puntos: 126
No sé si alcancé a visualizar tu problema .. pero en principio (si entendí bien) .. Deberías aporta datos sobre la estructura de tu BD (si es que la usas) .. y que es lo que requieres obtener de los datos que actualmente gestiones.

Un saludo,
  #3 (permalink)  
Antiguo 16/03/2005, 15:02
 
Fecha de Ingreso: noviembre-2002
Mensajes: 59
Antigüedad: 15 años
Puntos: 0
Los datos de la tabla categoria es sencilla:

Código:
CREATE TABLE tipos (
  id mediumint(8) NOT NULL auto_increment,
  tipo varchar(50) NOT NULL default '',
  posicion mediumint(8) NOT NULL,
  foto varchar(40) NOT NULL default 'n/a',
  UNIQUE KEY id (id),
  KEY tipo (tipo)
) TYPE=MyISAM;
La de productos aun no esta hecha pero simplemente puede ser así:

Código:
CREATE TABLE productos (
  id mediumint(8) NOT NULL auto_increment,
  tipo varchar(50) NOT NULL default '',
  producto varchar(50) NOT NULL default '',
  descripcion text,
  UNIQUE KEY id (id),
) TYPE=MyISAM;

Espero que te sirva esto más información la que quieras

Última edición por jonai; 16/03/2005 a las 15:10
  #4 (permalink)  
Antiguo 16/03/2005, 15:06
Avatar de nicolaspar  
Fecha de Ingreso: noviembre-2004
Ubicación: Villa Ballester Bs-As|Ar
Mensajes: 2.002
Antigüedad: 13 años
Puntos: 34
Para que necesitas dos auto_increment??. Si lo que necesitas es un campo para ordenar los registros en pantalla del lado del php, con un campo int basta.
__________________
Mi punto de partida es Que Bueno Lo Nuevo
  #5 (permalink)  
Antiguo 16/03/2005, 15:14
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 15 años, 11 meses
Puntos: 126
Con el nombre de las tablas me confundí .. Pero .. realmente por qué orden deseas ordenar tus consultas SQL ?

Quieres ordenar esa tabla (sus resultados al consultarla) por el campo TIPO? que va a definir en un campo numérico el orden que ha de aparecer (independiente del auto-numérico que ya sabes no puedes cambiarlo por motivos de "integridad referencial").

Si es así .. en principio .. si tu defines ese valor de tu registro con un valor .. y el resto "0" .. vas a ordenar por ese campo (posicionando primero los que tengas "numerados") y el resto como están .. es decir . .no es neceario que "numeres" todos los registros de esa tabla .. Eso sí .. si borras alguno tendrás que "regenerar" ese "indice".

El caso es .. visto esa relación que vas a tener en tus tablas .. no se debería ocasionar que borres un "tipo" si además está relacionado en tu "producto" .. pues perderías toda "integridad referncial" de los datos .. a lo sumo borrar en "cascada" todo registro que intervenga dicho dato. A lo sumo haras un borrado "lógico" .. es decir .. un campo extra que defina su "activado/desactivado o inhabilitado" para no volverlo a usar más .. pero cada a "historial" quedará ese registro y relación establecida .. Tal vez esto lo tengas claro ya .. pero bueno .. es para que veas que tal vez te estás "liando" para hacer alguna taréa que no debería suceder nunca.

(ya nos estamos metiendo en SQL .. sería cosa de tratarlo en el foro de "Base de datos" .. Pero bueno .. veamos si corresponde hacerlo en PHP o PHP+SQL)

Un saludo,
  #6 (permalink)  
Antiguo 16/03/2005, 15:16
 
Fecha de Ingreso: noviembre-2002
Mensajes: 59
Antigüedad: 15 años
Puntos: 0
Mi problema es que no se mucho de php ni de mysql, y saco mis scripts a base de estudiar el código libre y la prueba y error, cómo funcionan los campos int. ¿se crean automáticamente como los auto_increment? si es así si me servirían. El código en cuestion que estoy utilizando es el siguiente:
Código:
<?
include("../includes/config.php");
include("../includes/funciones.php");
// para asignar posicion de cada nueva categoria
$cnx = conectar();
$res0 = "SELECT * FROM tipos"; 
$result = mysql_query($res0); 
$num = mysql_num_rows($result); 
$numtot = $num + "1";
mysql_close($cnx);
// fin para asignar posicion de cada nueva categoria

if(isset($_POST['submit'])){
	$error = false;
	// si hay imagen.
	if (is_uploaded_file($_FILES['imagen']['tmp_name'])) {
		//revisamos que sea jpg
		if ($_FILES['imagen']['type'] == "image/jpeg" || $_FILES['imagen']['type'] == "image/pjpeg"){
			//nombre de la imagen
			$foto = time().".jpg";
			//movemos la imagen.
			move_uploaded_file($_FILES['imagen']['tmp_name'], "../img/tipos/".$foto);
		}else{
			$error = true;
			$errormsg = "Formato no válido para archivo de imagen";
		}
	} else {
		//imagen no se pudo subir o no seleccionaron.
		$error=true;
		$errormsg = "Error al cargar imagen: " . $_FILES['imagen']['name'];
	}//fin file upload.
		
	//continuamos con el insert.
	//si hay error no hay imagen.
	if($error){
		$foto = "N/A";
	}
	$descripciona = str_replace("\r","",$_POST['descripcion']);
	$campos = "tipo,descripcion,posicion,foto";
	$valores = "'".$_POST['tipo']."','$descripciona','$posicion','$foto'";
	//nos conectamos a la bd.
	$cnx = conectar();
	$res = mysql_query("INSERT INTO tipos ($campos) VALUES($valores)") or die (mysql_error());
	//cerramos la conexión.
	mysql_close($cnx);
	//mensaje de exito.
	$titulo = "TIPO INCLUIDO";
	$mensaje = "El registro se ha incluido con exito";
	$link = "<a href='tipos.php'>regresar</a>";
	include("mensajes_tipos.php");
	exit;
}
include("secure.php");


?>

<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<LINK href="css/estilo.css" type=text/css rel=stylesheet>
</head>

<body leftMargin=0 topMargin=0 marginheight="0" marginwidth="0">
<center>
<table width="800" height="100%" border="0" cellpadding="0" cellspacing="0">
  <tr> 
    <?php include ("top.php3"); ?>
  </tr>
  <tr> 
    <td width="180" valign="top" class="caja02"><?php include ("menu.php"); ?></td>
    <td width="620" valign="top" class="caja02">
<table width="100%">
<tr><td>
| <a href="configura.php">CONFIGURACION</a> | <a href="tipos.php">ADMINISTRAR TIPOS</a> |
</td></tr>
</table>

<form action="<? echo $SERVER['PHP_SELF']?>" method="post" enctype="multipart/form-data" name="PostTopic">
<table width="100%">
<tr><td>

<table width="100%">
	   <tr>
      <td height="30">Insertar tipo.</td>
    </tr>
    <tr>
      <td>&nbsp;</td>
    </tr>
    <tr>
                    <td>TIPO:<br>
        <input name="tipo" type="text" id="tipo" size="40">
      </td>
    </tr>
	<tr>
                    <td>POSICION:<br>
					<select id="posicion" name="posicion">
  <option value="<? echo $numtot;?>"><? echo $numtot;?></option>
  <option value="1">1</option>
  <option value="2">2</option>
  <option value="3">3</option>
  <option value="4">4</option>
  <option value="5">5</option>
  <option value="6">6</option>
  <option value="7">7</option>
  <option value="8">8</option>
  <option value="9">9</option>
  <option value="10">10</option>
  <option value="11">11</option>
  <option value="12">12</option>
  <option value="13">13</option>
  <option value="14">14</option>
  <option value="15">15</option>
  <option value="16">16</option>
  <option value="17">17</option>
  <option value="18">18</option>
  <option value="19">19</option>
  <option value="20">20</option>
</select>
      </td>
    </tr>
    <tr>
      <td>Descripcion:<br>
        <textarea name="descripcion" cols="40" rows="6" id="descripcion"></textarea>
      </td>
    </tr>

    <tr>
                    <td>Imagen:
					
<!-- type="hidden" --> 
                      <input type="hidden" name="MAX_FILE_SIZE" value="100000">
      <br>
      <input name="imagen" type="file" id="imagen"></td>
    </tr>
    <tr>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <td align="right"><input name="submit" type="submit" id="submit" value="Enviar"></td>
    </tr>

</table>

</td>
</tr>

</table>

</form>

    </td>
  </tr>
  <tr> 
    <?php include ("botton.php3"); ?>
  </tr>
</table>
</center>
</body>
</html>
Así es como lo estoy haciendo y en el siguiente post está lo que me gustaría conseguir.

Última edición por jonai; 16/03/2005 a las 15:24
  #7 (permalink)  
Antiguo 16/03/2005, 15:22
 
Fecha de Ingreso: noviembre-2002
Mensajes: 59
Antigüedad: 15 años
Puntos: 0
La cuestion es que las categorias las querría mostrar conforme a un orden determinado en la pantalla php de resultados, por eso pienso que es más cómodo asignar un valor inicial que se correspondería con ese "segundo auto_increment virtual" para poder modificarlo mediante updates concadenados como se hace en el siguiente código:

Código:
if($action==hoch)
{
	//Alle einlesen die ID<$ID / get all ID's<$ID
	$get_main=mysql_query("SELECT * FROM $maintable WHERE ID<$ID ORDER BY ID");
	while($row=mysql_fetch_object($get_main))
	{
	$above=$row->ID;
	}
		if (empty($above)){echo "Der Menüpunkt ist schon ganz oben<br><br>";}
		//$above ist jetzt die letzte vorhandene ID über der ausgewählten / $above is last ID above the one which was selected
		else 	{
		$update_1=mysql_query("UPDATE $maintable Set ID = 00000000 WHERE ID = '$above'");
		$update_2=mysql_query("UPDATE $maintable Set ID = '$above' WHERE ID = '$ID'");
		$update_3=mysql_query("UPDATE $maintable Set ID = '$ID' WHERE ID = 00000000");
		}
}
//Kategorie nach unten schieben / move categorie down

if($action==runter)
{
		//Alle einlesen die ID>$ID / get all ID's<$ID
		$get_main=mysql_query("SELECT * FROM $maintable WHERE ID>$ID ORDER BY ID DESC");

		while($row=mysql_fetch_object($get_main))
		{
		$below=$row->ID;
		}
		if (empty($below)){echo "Der Menüpunkt ist schon ganz unten<br><br>";}
		//$below ist jetzt die erste vorhandene ID nach der ausgewählten / $below is first ID below the one which was selected
		else 	{
		$update_4=mysql_query("UPDATE $maintable Set ID = 00000000 WHERE ID = '$below'");
		$update_5=mysql_query("UPDATE $maintable Set ID = '$below' WHERE ID = '$ID'");
		$update_6=mysql_query("UPDATE $maintable Set ID = '$ID' WHERE ID = 00000000");
		if($update_4==true && $update_5==true && $update_6==true) {}
		else {echo "Es traten Fehler auf";}
}
El script está en aleman pero creo se entiende lo que hace.
Mi problema es ese mismo que comentas, es decir no puedo usar el id ya que me crearía inconsistencia con respecto a la tabla productos, de ahí mi interés de simularlo.
  #8 (permalink)  
Antiguo 16/03/2005, 15:37
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 15 años, 11 meses
Puntos: 126
(sigo sin comprender .. pero haré el intento) ... en las funciones de Mysql tienes la función:

mysql_insert_id() (www.php.net/mysql_insert_id) para obtener el último ID generado por una instrucción SQL ..

Eso es lo que se suele usar para hacer relaciones entre tablas es decir .. creando el registro en una tabla (A) y de ahí crear un registro relacionado en otra tabla (B) en una misma secuencia:

tabla A
id_tabla_A
campo
campoX

tabla B
id_tabla_B
id_tabla_A <-- clave foránea .. campo clave que nos relacionará ambas tablas ..
campoX
campoETC

De esa forma .. tu creas el registro en la tabla A que tiene el campo ID_tabla_A tipo autonumérico (igual que todas las demás tablas) .. obtienes ese ID generado y se lo pasas a la otra tabla en el otro INSERT ...

Código PHP:
// crear registro en tabla "Padre" .. 
$sql="INSERT INTO tablaA (id_tabla_a,etc....) VALUES ('',"datos")";
mysql_query($sql);
$id_tabla_a=mysql_insert_id($consulta);

// crear registros tablas hijas ..
$sql="INSERT INTO tablaB (id_tabla_b,id_tabla_a,etc ...) VALUES ('','$id_tabla_a','datos')";
mysql_query($sql); 
No sé si es eso lo que buscabas o ya me perdí del todo .. pero creo que tu problema va por ahí ..

Un saludo,
  #9 (permalink)  
Antiguo 16/03/2005, 15:53
 
Fecha de Ingreso: noviembre-2002
Mensajes: 59
Antigüedad: 15 años
Puntos: 0
Gracias por la explicación, pero lo más seguro es que me haya explicado yo mal desde el principio (aunque todo lo dicho por aquí no va a caer en saco roto, te lo aseguro), vamos a ver.

Nos vamos a olvidar de la segunda tabla, la que se refiere a los productos, de momento no me sirve de nada.

Y me centro en la primera tabla la de las categorias.
Bien, en principio cada categoría va a tener su id auto_increment único, pero dicho id no lo puedo utilizar para ordenar los resultados ya que éstos se mostrarán siguiendo un orden diferente a la entrada de los mismos. Así sólo se me ocurre crear un segundo id_b "auto_increment virtual" (que ya se que no se puede hacer directamente) que sí podré modificar a mi gusto mediante un script similar al que muestro arriba.

Bien mi pregunta sería cómo hago ese segundo "auto_increment virtual" mi respuesta sería la siguiente:
Código:
// para asignar posicion de cada nueva categoria
$cnx = conectar();
$res0 = "SELECT * FROM tipos"; 
$result = mysql_query($res0); 
$num = mysql_num_rows($result); 
$numtot = $num + "1";
mysql_close($cnx);
// fin para asignar posicion de cada nueva categoria
Pero tiene el problema de que posiblemente se puedan duplicar los valores (auque con tu idea de desactivarlos en vez de borrarlos podría solucionar ese punto). En fin espero haber sido más claro esta vez.

Y de verás agradecido por la prontitud y rapidez en tus respuestas (simpre acertadas)

Última edición por jonai; 16/03/2005 a las 15:54
  #10 (permalink)  
Antiguo 16/03/2005, 16:01
Avatar de nicolaspar  
Fecha de Ingreso: noviembre-2004
Ubicación: Villa Ballester Bs-As|Ar
Mensajes: 2.002
Antigüedad: 13 años
Puntos: 34
Para eso crea un nuevo campo llamado "orden" del tipo int 10, y ahi pones el orden que quieras, luego en el query haces "...order by orden". No es necesario un autoincrement. Y si queres, podes hacer una interface en php para que el administrador pued avriar estos ordenes.
__________________
Mi punto de partida es Que Bueno Lo Nuevo
  #11 (permalink)  
Antiguo 17/03/2005, 06:14
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 15 años, 11 meses
Puntos: 126
Si tu problema principal es que no sabes como darle ese "orden" automático .. en principio (hasta que se borre algún registro si es que corresponde) puedes dar el mismo ID que ya genera tu campo tipo "autoincrement" ...(y lo puedes obetener con mysql_insert_id() cuando hagas tu "INSERT" para hacer un UPDATE sobre el campo "orden" o hasta con SQL a lo mejor se puede hacer alguna referencia directa tipo INSERT INTO Tabla (id_autonumerico,orden) VALUES ('',id_autonumerico) .. esto habría que probarlo).

Ahora .. cuando tu orden cambia ya sea por qué borras un registro o se ha de cambiar su orden pre-definido . . Tendrás que crear una aplicación para gestionar eso, donde una de las cosas que tendras que hacer es regenerar ese Orden siempre .. De hecho .. si tu el campo orden .. por defecto usas "0" ordenando tipo ORDER BY orden ordenas por dicho campo .. si no tiene valor .. se usa el "ID" (en realidad .. será tal cual se ingresaron secuencialmente) .. Si tienes que "ordenar" .. tan sólo tienes que poner el N° de orden que corresponda .. A no ser que tengas un real desorden total de toda la tabla ... en principio hacer taréas tipo "colocar" este u otro producto de los primeros (o un grupo reducido) podrías gestionarlo comodamente ..

El orden lo debería crear "manualmente" el usuario de tu aplicación (quien lo defina) .. Muestras todos los registros en una página y su "input" para tu campo orden .. ahí que lo defina tu usuario .. tu sólo haces luego un "UPDATE" a ese campo con el valor que se le otorgue. Si borras uno .. no sé como te lo vas hacer .. en teoría tendrías que ir recorriendo todos los registros menores a "orden" del campo borrado y restar 1 .. (así a la rápida) ...

Un saludo,
  #12 (permalink)  
Antiguo 17/03/2005, 06:59
Avatar de nicolaspar  
Fecha de Ingreso: noviembre-2004
Ubicación: Villa Ballester Bs-As|Ar
Mensajes: 2.002
Antigüedad: 13 años
Puntos: 34
Lo mejor para ordenar (sigueindo con el post de Cluster), es hacer un listado con los registros, y ponerle una flechita para bajar, y otra para subir el registro, mas que un input libre.
__________________
Mi punto de partida es Que Bueno Lo Nuevo
  #13 (permalink)  
Antiguo 17/03/2005, 08:04
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 15 años, 11 meses
Puntos: 126
Cita:
Iniciado por nicolaspar
Lo mejor para ordenar (sigueindo con el post de Cluster), es hacer un listado con los registros, y ponerle una flechita para bajar, y otra para subir el registro, mas que un input libre.
Ok .. todo eso es completamente válido a nivel de "usabilidad" .. En tal caso todo eso ya no se hace con PHP sino con Javascript. El objetivo final es el mismo: generar ese orden para cada uno de los registros mostrados en la página.

Un saludo,
  #14 (permalink)  
Antiguo 17/03/2005, 08:22
Avatar de nicolaspar  
Fecha de Ingreso: noviembre-2004
Ubicación: Villa Ballester Bs-As|Ar
Mensajes: 2.002
Antigüedad: 13 años
Puntos: 34
Si, totalmente de acuerdo, esto se salio del thread original :P
__________________
Mi punto de partida es Que Bueno Lo Nuevo
  #15 (permalink)  
Antiguo 18/03/2005, 11:52
 
Fecha de Ingreso: noviembre-2002
Mensajes: 59
Antigüedad: 15 años
Puntos: 0
Pues si, y perdon por tardar en escribir de nuevo finalmente he hecho algo parecido, sigo utilizando el generador de posicion que puse antes, tan sólo para asignar el valor inicial de orden, y posteriormente lo modifico si fuera preciso mediante una página de edición, el problema no era que dos filas tuvieran la misma posición (ya que las ordeno también mediante el id), con eso soluciono parcialmente el problema, y para finalizarlo completamente en lugar de borrar el registro (que veo trae muchos problemas) lo activo o desactivo en función de la necesidad del momento.

Cuando termine la aplicación prometo subirla, aun esta en fase beeeeeeeeeeeeta, si se me permite dicha denominación como equivalente a "en pañales".

Un saludo y gracias.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 07:31.