¿Como hacer una consulta de una tabla con llaves foráneas de un determinado id?

publicado por: Anonymous

Cordial saludos, el problema que tengo es sobre una consulta. Quiero que me busque todos los abonos de un prestamo en especifico. La consulta que tengo me arroja son todos los abonos de todos los prestamos, la verdad no se cual es el error logico.

me puse a ejecutar el sql con phpmyadmin y me funciona me trae solo los abonos de un prestamo especifico pero cuando la ejecuto con el id_prestamo que traigo del formulario no me lo lista, si no me lista todos. Dedusco que hay algo que esta fallando en el paso del id_prestamo al listado del archivo abonos.php

Esta es la base de datos:Base de datos relacional

Este archivo prestamos.php donde lista todos los prestamos y tiene un enlace donde dice “ver abonos” que es donde me lleva al archivo abono_esepcifico.php donde hace el proceso de mostrar solo los abonos del determinado prestamo y me lleva al listado de los abonos al archivo abonos.php

Este es el archivo prestamos.php :

<?php

require('../conexion.php');
include('../menu/menu.php');
$con=Conectar();

//recibimos variable que llegan por metodo post o en el arreglo post
extract ($_REQUEST);
if (!isset ($_REQUEST['x'])) // si se desconoce la variable x se asigna el 
valor de 0
$x=0;

$sql="SELECT id_prestamo, pre_cliente, fecha, monto, forma_de_pago, fiador, 
cliente.cedula,cliente.nombre, cliente.apellido from prestamo
inner join cliente
on prestamo.pre_cliente=cliente.id_cliente
ORDER BY id_prestamo ASC";

?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Prestamos</title>
<meta name="viewport" content="wid=device-wid, user-scalable=no, initial-
scale=1.0, minium-scale=1.0">

</head>
<body>
<div class="container col-lg-12" >
<br>
<div class="panel panel-success">
<div class="panel-heading" align="center"><h3>PRESTAMOS</h3></div>
<div class="panel-body">

<div class="row" align="center">
<button type="button" class="btn btn-success" data-toggle="modal" data-
target="#nuevo">
Nuevo prestamo
</button></div>
<br>

<!--      clase para colocar tabla responsive-->
<div class="table-responsive">
<table id="grid" class="table table-hover table-condensed table-bordered 
nowrap dt-responsive" cellpadding="0">
<thead>
<tr class="active">

<th>Cedula</th>
<th>Cliente</th>
<th>Monto $ </th>
<th>No Cuotas</th>
<th>Interes %</th>
<th>Fecha Prestamo</th>
<th>Fiador</th>
<th>Forma de pago</th>
<th>Saldo actual</th>
<th>Abonos</th>
<th>Opciones</th>

</tr>
</thead>
<?php

$stmt=$con->prepare($sql);
$resultado=$stmt->execute();
$rows=$stmt->fetchAll(PDO::FETCH_OBJ);

foreach ($rows as $prestamo) {

?>

<tr>
<td><?php echo $prestamo->cedula?></td>
<td><?php echo $prestamo->nombre." ".$prestamo->apellido?></td>
<td><?php echo $prestamo->monto?></td>
<td></td>
<td></td>
<td><?php echo $prestamo->fecha?></td>
<td><?php echo $prestamo->fiador?></td>
<td><?php echo $prestamo->forma_de_pago?></td>
<td></td>

// este es el enlace que me lleva al archivo para hacer el proceso del query

<td><a href="../abonos/abono_especifico.php?id_prestamo=<?php echo 
$prestamo->id_prestamo ?>">Ver abonos</a>

&nbsp;
<button type="button" class="btn btn-success btn-sm"><a 
href="../abonos/frm_abonar.php?id_prestamo=<?php echo $prestamo->id_prestamo 
?>" style="text-decoration: none; color:#000;" >Abonar</button></a>
</td>
<td align="center"><a href="frm_editar.php?id_prestamo=<?php echo $prestamo-
>id_prestamo?>"><span class="glyphicon glyphicon-check" title="Editar">
</span></a>
&nbsp;
<a href="eliminar.php?id_prestamo= <?php echo $prestamo->id_prestamo?>">
<span class="glyphicon glyphicon-remove" title="Eliminar"></span></a></td>
<?php
}
?>
</tr>
</table>
</div>

<div align="center">
<br /><br />

<?php
if ($x==1) {
echo '<div class="alert alert-success alert-dismissable" data-
dismiss="alert" style="width:300px">Se actualizado el prestamo 
correctamente</div>';
}
if ($x==2) {
echo '<div class="alert alert-danger alert-dismissable" data-dismiss="alert" 
style="width:300px">Problemas al actualizar el prestamo</div>';
}
if ($x==3) {
echo '<div class="alert alert-success alert-dismissable" data-
dismiss="alert" style="width:300px">Se ha eliminado el prestamo 
correctamente</span>';
}
if ($x==4) {
echo '<div class="alert alert-success alert-dismissable" data-
dismiss="alert" style="width:300px">Problemas al eliminar el prestamo,  
Primero elimina el prestamo</div>';
}
if ($x==5){
echo '<div class="alert alert-success alert-dismissable" data-
dismiss="alert" style="width:300px">Se ha agregado el prestamo correctamente 
</div>';
}
if ($x==6){
echo '<div class="alert alert-success alert-dismissable" data-
dismiss="alert" style="width:300px">Problemas al agregar el prestamo</div>';
}
?>
</div>       
</div>
</div> 
</div>
</body>
</html>

Este es el archivo donde realizo las consulta:

abono_especifico.php

<?php

//archivo para la conexion
require "../conexion.php";
$con=Conectar();

$prestamo=$_REQUEST['id_prestamo'];

$sql="SELECT a.id_abono, a.abo_prestamo, a.fecha, a.cantidad, a.observacion, 
p.pre_cliente, c.cedula,c.nombre, c.apellido from abono a, prestamo p, 
cliente c
where a.abo_prestamo='$prestamo'
and p.pre_cliente=c.id_cliente
ORDER BY id_abono ASC";


$resultado=$con->prepare($sql);

$resultado->execute();


if ($resultado){
header ("location: abonos.php?x=7");//x=5 abonos encontrado
}else{
header ("location: abonos.php?x=8");//x=6 error al buscar el abono
}
$resultado->closeCursor();
?>

Este es el archivo que me lista los abonos, abonos.php

<?php

require('../conexion.php');
include('../menu/menu.php');
$con=Conectar();

//recibimos variable que llegan por metodo post o en el arreglo post
extract ($_REQUEST);
if (!isset ($_REQUEST['x'])) // si se desconoce la variable x se asigna el 
valor de 0
$x=0;

$sql="SELECT a.id_abono, a.abo_prestamo, a.fecha, a.cantidad, a.observacion, 
p.pre_cliente, c.cedula,c.nombre, c.apellido from abono a, prestamo p, 
cliente c
where a.abo_prestamo=p.id_prestamo
and p.pre_cliente=c.id_cliente
ORDER BY id_abono ASC";

?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Abonos</title>
<meta name="viewport" content="wid=device-wid, user-scalable=no, initial-
scale=1.0, minium-scale=1.0">
</head>

<body>
<div class="container" >
<br>
<div class="panel panel-success">
<div class="panel-heading" align="center"><h3>ABONOS</h3></div>
<div class="panel-body">
<div class="table-responsive">
<table id="grid" class="table  table-bordered  table-hover table-condensed">
<thead>
<tr class="active">
<th>Cedula</th>
<th>Cliente</th>
<th>Descripcion</th>
<th>Fecha</th>
<th>Abono $</th>
<th >Saldo $</th>
<th>Opciones</th>
</tr>
</thead>

<?php
$stmt=$con->prepare($sql);
$resultado=$stmt->execute();
$rows=$stmt->fetchAll(PDO::FETCH_OBJ);

foreach ($rows as $abono) {
?>

<tr>
<td><?php echo $abono->cedula?></td>
<td><?php echo $abono->nombre. " ".$abono->apellido?></td>
<td><?php echo $abono->observacion?></td>
<td><?php echo $abono->fecha?></td>
<td><?php echo $abono->cantidad?></td>
<td></td>

<td align="center"><a href="frm_editar.php?id_prestamo=<?php echo $prestamo-
>id_prestamo?>"><span class="glyphicon glyphicon-check" title="Editar">
</span></a>
&nbsp;

<a href="eliminar.php?id_prestamo= <?php echo $prestamo->id_prestamo?>">
<span class="glyphicon glyphicon-remove" title="Eliminar"></span></a></td>

<?php
}
?>

</tr>
</table>
<div align="center">
<br /><br />

<?php
if ($x==1) {
echo '<span style="color:black">Se actualizado el Abono 
correctamente</span>';
}
if ($x==2) {
echo '<span style="color:black">Problemas al actualizar el Abono</span>';
}
if ($x==3) {
echo '<span style="color:black">Se ha eliminado el Abono 
correctamente</span>';
}
if ($x==4) {
echo '<span style="color:black">Problemas al eliminar el Abono</span';
}
if ($x==5){
echo '<span style="color:black">Se ha agregado el Abono 
correctamente</span';
}
if ($x==6){
echo '<span style="color:black">Problemas al agregar el Abono</span>';
}
if ($x==7){
echo '<span style="color:black">Abonos encontrados</span>';
}
if ($x==8){
echo '<span style="color:black">Problema al encontrar los abonos</span>';
}
?>

</div>
</div>
</div>
</div>
</div>

</body>
</html>

Por ultimo dejo el archivo de conexion.php

<?php

function Conectar(){
$conn=null;
$host='localhost';
$db='prestamos';
$us='root';
$pass='';

try {
    $conn= new PDO('mysql:host='.$host.';dbname='.$db, $us, $pass);
} catch (PDOException $e) {
    echo ":( Error al conectar a la base de datos".$e;
    exit;
}
return $conn;
}

?>

Se les agradecería una pronta respuesta.

solución

Creo que esto es lo que necesitas.

Verás que la consulta utiliza JOINS en vez de usar WHERE, porque es recomendable usar este tipo de uniones, son más eficaces y menos costosas.

Sencillamente los JOINS unen las tablas por las llaves primarias/foráneas de cada una y traen los registros.

Es un ejemplo básico el cual puedes adaptar, aplicando los filtros, orden, columnas, agrupaciones que quieras.

En el ejemplo se consultan los abonos que hechos el prestamo con el id_prestamo = 1.


DEMO SQL Fiddle

MySQL 5.6 Schema Setup:

CREATE TABLE cliente
    (`id_cliente` int, `nom_cliente` varchar(70))
;

INSERT INTO cliente
    (`id_cliente`, `nom_cliente`)
VALUES
    (1, 'Pedro'),
    (2, 'Santiago'),
    (3, 'Juan')
;

CREATE TABLE prestamo
    (`id_prestamo` int, `pre_cliente` int, `monto` float)
;

INSERT INTO prestamo
    (`id_prestamo`, `pre_cliente`, `monto`)
VALUES
    (1, 1, 1000.00),
    (2, 2, 23000.00),
    (3, 3, 1000000.10)
;

CREATE TABLE abono
    (`id_abono` int, `abo_prestamo` int, `cantidad` float)
;

INSERT INTO abono
    (`id_abono`, `abo_prestamo`, `cantidad`)
VALUES
    (1, 1, 100.00),
    (2, 2, 300.00),
    (3, 3, 1500.00),
    (4, 1, 200.00)   
;

Query 1:

SELECT
  c.nom_cliente, p.id_prestamo, a.id_abono, a.cantidad
FROM 
  prestamo p

  LEFT JOIN cliente c ON p.pre_cliente=c.id_cliente
  LEFT JOIN abono a ON p.id_prestamo=a.abo_prestamo

  WHERE p.id_prestamo=1

Results:

| nom_cliente | id_prestamo | id_abono | cantidad |
|-------------|-------------|----------|----------|
|       Pedro |           1 |        1 |      100 |
|       Pedro |           1 |        4 |      200 |

NOTA:

Sobre tu código PHP quiero señalar que el mismo es vulnerable a la Inyección SQL, ya que no es una buena práctica enviar juntas a la base de datos la consulta y los datos, se recomienda usar consultas preparadas que separen lo que es la instrucción SQL y los datos.

Por ejemplo, esta consulta es vulnerable a la inyección SQL:

$sql="SELECT a.id_abono, a.abo_prestamo, a.fecha, a.cantidad, a.observacion, 
p.pre_cliente, c.cedula,c.nombre, c.apellido from abono a, prestamo p, 
cliente c
where a.abo_prestamo=p.id_prestamo
and p.pre_cliente=c.id_cliente
ORDER BY id_abono ASC";

Significa que en ella se puede introducir código malicioso y se ejecutaría tal cual, pudiendo tener consecuencias desastrosas.

Entonces habría que prepararla, por ejemplo:

$sql="SELECT a.id_abono, a.abo_prestamo, a.fecha, a.cantidad, a.observacion, 
p.pre_cliente, c.cedula,c.nombre, c.apellido from abono a, prestamo p, 
cliente c
where a.abo_prestamo=?
and p.pre_cliente=?
ORDER BY id_abono ASC";

Lo que se hace en una consulta preparada es sustituir los datos que vienen de fuera por signos de interrogación (hay otros métodos) y luego enviar esos datos por otro lado, a través de binding. Es un tema un poco largo, te recomiendo que leas el enlace indicado más abajo.

El problema es que si en esta consulta el valor que envías para c.id_cliente es tomado de un formulario y un usuario malicioso escribe esto: 1; DELETE FROM cliente; # estaría enviando un id_cliente igual a uno y al mismo tiempo una consulta para borrar tu tabla clientes, comentando con el signo de # todo el resto de la consulta (ORDER BY id_abono ASC) y tu tabla clientes sería borrada indefectiblemente. Eso es lo que se llama Inyección SQL.

Para más detalles sobre esto consulta esta pregunta y sus respuestas: ¿Cómo evitar la inyección SQL en PHP?

Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *