Foreign Key not linking correctly - php

When registering my first user in table 'users' the id is the same value as user_id in the linking table,1, (language). However, when I register another user (id2 in users) the user_id in language is still 1. See SQL:
CREATE TABLE `language` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`native` varchar(30) NOT NULL,
`other` varchar(30) NOT NULL,
`other_list` varchar(9) NOT NULL,
`other_read` varchar(9) NOT NULL,
`other_spokint` varchar(9) NOT NULL,
`other_spokprod` varchar(9) NOT NULL,
`other_writ` varchar(9) NOT NULL,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=9 ;
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`md5_id` varchar(200) NOT NULL,
`full_name` tinytext CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
`user_name` varchar(10) NOT NULL,
`user_email` varchar(30) NOT NULL,
`user_level` tinyint(4) NOT NULL DEFAULT '1',
`pwd` varchar(220) NOT NULL,
`nationality` varchar(30) NOT NULL,
`department` varchar(20) NOT NULL,
`birthday` date NOT NULL,
`date` date NOT NULL DEFAULT '0000-00-00',
`users_ip` varchar(200) NOT NULL,
`activation_code` int(10) NOT NULL DEFAULT '0',
`banned` int(1) NOT NULL,
`ckey` varchar(200) NOT NULL,
`ctime` varchar(220) NOT NULL,
`approved` int(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
This is my PHP code:
if(empty($_SESSION['$user_id'])) { // user not logged in; redirect to somewhere else }
if (!empty($_POST['doLanguage']) && $_POST['doLanguage'] == 'Submit')
{
$result = mysql_query("SELECT `id` FROM users WHERE `banned` = '0'") or
die (mysql_error());
list($id) = mysql_fetch_row($result);
session_start();
$_SESSION['user_id']= $id;
sql_insert = "INSERT into `language`
(`user_id`,`native`,`other`,`other_list`,`other_read`, `other_spokint`
,`other_spokprod`,`other_writ` )
VALUES
('$id','$native','$other','$other_list','$other_read','$other_spokint',
'$other_spokprod','$other_writ') ";
mysql_query($sql_insert,$link) or die("Insertion Failed:" . mysql_error());
}
header("Location: myaccount.php?id=' . $_SESSION[user_id] .'");
exit();
Would appreciate any help!

I think this is because your initial select query is selecting all users that are not banned
So need to change the query to filter by the new user:
"SELECT `id` FROM users WHERE `banned` = '0' and id=" . $_SESSION['$user_id'];
The reason why the user_id field kept getting populated as 1 was because mysql_fetch_row was getting the first record which was user id 1.
So if you filter it by the new user, mysql_fetch_row should get the id of the new user.
EDIT
I'm just looking at the code again, and it looks like you do not store the user id in php after you insert it, so your user_id for $_SESSION is null.
So my above example will not work. Instead of the above query, use the following function to get the id of your newly created user. You call this function after you run your insert query. That function will get the new of your newly created user.
mysql_insert_id()
http://php.net/manual/en/function.mysql-insert-id.php
EDIT 2
Ok, since mysql_insert_id() didn't work for you, maybe you can try the following. I just changed your select query to order by id desc.
$result = mysql_query("SELECT `id` FROM users WHERE `banned` = '0' order by id desc")
Just a note, this is probably not the best solution. But on a low traffic website it should be fine. To make the query a bit more accurate, you'd want to search for the user id based on a unique field like a username or email. This would make sure you get the correct id back.
EDIT 3
Here is an example of checking for the user's email. This is just the mysql query, you'll have to adjust this for php. Sorry I'm in class right now.
"SELECT `id` FROM users WHERE `banned` = '0' and email='user#email.com' limit 1

Related

Query for inserting last_insert_id() produce the same id value

Here's my info table:
CREATE TABLE `info` (
`id_info` int(10) NOT NULL auto_increment,
`judul_info` varchar(50) collate latin1_general_ci NOT NULL,
`konten` varchar(255) collate latin1_general_ci NOT NULL,
`diubah_oleh` varchar(20) collate latin1_general_ci NOT NULL,
`id_kategori` int(10) NOT NULL,
`tgl_buat` timestamp NOT NULL default '0000-00-00 00:00:00',
`tgl_ubah` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`dibuat_oleh` varchar(20) collate latin1_general_ci NOT NULL,
`id` int(10) NOT NULL,
PRIMARY KEY (`id_info`),
KEY `id_kategori` (`id_kategori`),
KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=62 ;
Here's my upload table
CREATE TABLE `upload` (
`id` int(10) unsigned NOT NULL auto_increment,
`deskripsi` text,
`filetype` varchar(200) default NULL,
`filedata` longblob,
`filename` varchar(200) default NULL,
`filesize` bigint(20) default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=34 ;
I'm using this query :
$sql1="INSERT INTO info VALUES('','$judul', '$konten','$diubah_oleh','$kategori',now(),'$tgl_ubah','$dibuat_oleh','')";
$sql2="insert into upload values ('','$keterangan','$tipe','$filedata','$nama_file',$ukuran)";
$sql3="UPDATE info SET id=last_insert_id()";
$result=mysql_query($sql1);
$result=mysql_query($sql2);
$result=mysql_query($sql3);
I want info.id has the same value as upload.id but with this query all of the value i get in info.id is the same as value i last inserted in upload.id.
CREATE TABLE `upload` (
`id` int(10) unsigned NOT NULL,
`deskripsi` text,
`filetype` varchar(200) default NULL,
`filedata` longblob,
`filename` varchar(200) default NULL,
`filesize` bigint(20) default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=34 ;
$sql1="INSERT INTO info VALUES('','$judul', '$konten','$diubah_oleh','$kategori',now(),'$tgl_ubah','$dibuat_oleh','')";
$result=mysql_query($sql1);
$lastId = mysql_insert_id();
$sql2="insert into upload values ('$lastId','$keterangan','$tipe','$filedata','$nama_file',$ukuran)";
$result=mysql_query($sql2);
Your last update statement below is updating all the rows in your info tables with the same id because there is no where statement.
Since you need the upload table id information inside the info table.
Follow these steps:
Run the $sql2 first.
Then run the $sql1 inserting the last_insert_id() in info.id.
This way you don't need to use update statement as well.
You can do this by using mysql_insert_id(). This function returns the AUTO_INCREMENT ID generated from the previous INSERT operation. Your code should look like this
$sql1="INSERT INTO info VALUES('','$judul', '$konten','$diubah_oleh','$kategori',now(),'$tgl_ubah','$dibuat_oleh','')";
$result=mysql_query($sql1);
$lastinsertedid= mysql_insert_id();
$sql2="insert into upload values ('$lastinsertedid','$keterangan','$tipe','$filedata','$nama_file',$ukuran)";
$result=mysql_query($sql2);
Hope this helps you
There is an alternate php function to that mysql_insert_id() . You can use this to generate the ID inserted in the last executed query.
can you try to do this:
$sql1="INSERT INTO info VALUES('','$judul', '$konten','$diubah_oleh','$kategori',now(),'$tgl_ubah','$dibuat_oleh','')";
$sql2="insert into upload values ('','$keterangan','$tipe','$filedata','$nama_file',$ukuran)";
$last_id = last_insert_id();
$sql3="UPDATE info SET id=".$last_id;
$result=mysql_query($sql1);
$result=mysql_query($sql2);
$result=mysql_query($sql3);

MySQL delete troubleshooting

I restarted the MySQL service and I attempted to use my PHP programs delete function to delete an existing row but I'm finding although the delete queries were counted the row was not deleted. I tried applying on delete cascade to the foreign key of the child table but that did not seem to have an effect. I'm wondering why the delete would be doing nothing.
CREATE TABLE `customers` (
`idcustomers` int(11) NOT NULL AUTO_INCREMENT,
`firstname` varchar(45) DEFAULT NULL,
`lastname` varchar(45) DEFAULT NULL,
`address1` varchar(45) DEFAULT NULL,
`address2` varchar(45) DEFAULT NULL,
`city` varchar(45) DEFAULT NULL,
`state` varchar(45) DEFAULT NULL,
`zip` varchar(45) DEFAULT NULL,
`phone` varchar(45) DEFAULT NULL,
`email` varchar(45) DEFAULT NULL,
`cell` varchar(45) DEFAULT NULL,
PRIMARY KEY (`idcustomers`),
UNIQUE KEY `idcustomers_UNIQUE` (`idcustomers`)
) ENGINE=InnoDB AUTO_INCREMENT=54 DEFAULT CHARSET=latin1
CREATE TABLE `events` (
`idevents` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(250) DEFAULT NULL,
`start` datetime DEFAULT NULL,
`end` datetime DEFAULT NULL,
`allday` varchar(50) DEFAULT NULL,
`url` varchar(1000) DEFAULT NULL,
`customerid` int(11) NOT NULL,
`memo` longtext,
`dispatchstatus` varchar(45) DEFAULT NULL,
PRIMARY KEY (`idevents`),
KEY `FK_events` (`customerid`),
CONSTRAINT `FK_events` FOREIGN KEY (`customerid`) REFERENCES `customers` (`idcustomers`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=latin1
Com_delete 2
The PHP looks like this:
<?php
session_start();
date_default_timezone_set("America/Los_Angeles");
if($_SESSION['loggedin'] != TRUE)
{
header("Location: index.php");
}
require_once('../php.securelogin/include.securelogin.php');
$mysqli = new mysqli($ad_host, $ad_user, $ad_password, "samedaycrm");
if ($mysqli->connect_errno) {
printf("Connect failed: %s\n", $mysqli->connect_error);
exit();
}
$customerid = $_SESSION['customer_id'];
$tSQL = "delete from events where customerid = \"$customerid\"";
$result = $mysqli->query($tSQL);
$tSQL = "delete from customers where idcustomers = \"$customerid\"";
$result = $mysqli->query($tSQL);
echo $mysqli->error;
?>
Assuming that the customerid and idcustomers columns are both numeric it should be fine. You should not need to quote the variables in those queries btw, then you wouldnt need to escape them. You may try:
$tSQL = "delete from events where customerid = $customerid";
but it should not be any different than what you used already. Of course if you are not sure of the type of the column you can use:
$tSQL = "delete from events where customerid = '".$customerid."'";
or you can get away with:
$tSQL = "delete from events where customerid = '$customerid'";
but I have always hated that for some reason.
if all of that fails troubleshoot by spitting out the $customerid (or even the whole $tSQL) variable and then trying the query manually in phpmyadmin or toad or whatever db client you use, and see what it tells you. If it just says 0 rows affected, then run it like a select instead. Tailor to fit.

Why mysql_insert_id returns 0 in my case?

This is my table:
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL auto_increment,
`name` varchar(20) NOT NULL default '',
`pass` varchar(32) NOT NULL default '',
`lang` varchar(2) default NULL,
`locale` varchar(2) default NULL,
`pic` varchar(255) default NULL,
`sex` char(1) default NULL,
`birthday` date default NULL,
`mail` varchar(64) default NULL,
`created` timestamp NOT NULL default CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `mail` (`mail`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=27 ;
And this is my query:
$query = "INSERT IGNORE INTO `users` (`name`, `mail`, `birthday`, `lang`, `locale`, `sex`, `pic`) VALUES ('".$name."', '".$email."', '".date_format($birthdaynew, 'Y-m-d H:i:s')."', '".substr($locale, 0, 2)."', '".substr($locale, -2, 2)."', '".$sex."', 'pic/".$uid.".jpg')";
$rows = mysql_query($query) or die("Failed: " . mysql_error());
$_SESSION['id'] = mysql_insert_id(); // I have tryed also mysql_insert_id($db_con) where $db_con is the link to db.
$_SESSION['name'] = $name;
$_SESSION['name'] contains correctly the name but $_SESSION['id'] contains 0.
Why ?
I'm going crazy!
Is there a particular reason why you are using INSERT IGNORE?
If you use INSERT IGNORE, then the row won't actually get inserted if there is a duplicate key (PRIMARY or UNIQUE), or inserting a NULL into a column with a NOT NULL constraint.
Referring to the pass column, as you have not defined anything to insert into it, and it has NOT NULL constraint.
EDIT:
Referring also to the mail column, as you have a UNIQUE constraint on it.

id not changing correctly

If I register a user using this table:
CREATE TABLE IF NOT EXISTS `users`
(
`id` INT(11) NOT NULL AUTO_INCREMENT,
`md5_id` VARCHAR(200) NOT NULL,
`full_name` TINYTEXT CHARACTER SET latin1 COLLATE latin1_general_ci
NOT NULL,
`user_name` VARCHAR(10) NOT NULL,
`user_email` VARCHAR(30) NOT NULL,
`user_level` TINYINT(4) NOT NULL DEFAULT '1',
`pwd` VARCHAR(220) NOT NULL,
`nationality` VARCHAR(30) NOT NULL,
`department` VARCHAR(20) NOT NULL,
`birthday` DATE NOT NULL,
`date` DATE NOT NULL DEFAULT '0000-00-00',
`users_ip` VARCHAR(200) NOT NULL,
`activation_code` INT(10) NOT NULL DEFAULT '0',
`banned` INT(1) NOT NULL,
`ckey` VARCHAR(200) NOT NULL,
`ctime` VARCHAR(220) NOT NULL,
`approved` INT(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`)
)
ENGINE=INNODB
DEFAULT CHARSET=latin1
AUTO_INCREMENT=3;
and then once logged in to 'myaccount.php' use this code to enter values into another table, the language table:
if (empty($_SESSION['$user_id'])) { // user not logged in; redirect to somewhere else }
if (!empty($_POST['doLanguage']) && $_POST['doLanguage'] == 'Submit') {
$result = mysql_query("SELECT `id` FROM users WHERE `banned` = '0' order by id desc");
list($id) = mysql_fetch_row($result);
session_start();
$_SESSION['user_id'] = $id;
foreach ($_POST as $key => $value) if (empty($err)) {
for ($i = 0;$i < count($_POST["other"]);$i++) {
$native = mysql_real_escape_string($_POST['native'][$i]);
$other = mysql_real_escape_string($_POST['other'][$i]);
$other_list = mysql_real_escape_string($_POST['other_list'][$i]);
$other_read = mysql_real_escape_string($_POST['other_read'][$i]);
$other_spokint = mysql_real_escape_string($_POST['other_spokint'][$i]);
$other_spokprod = mysql_real_escape_string($_POST['other_spokprod'][$i]);
$other_writ = mysql_real_escape_string($_POST['other_writ'][$i]);
$sql_insert = "INSERT into `language`
(`user_id`,`native`,`other`,`other_list`,`other_read`, `other_spokint`
,`other_spokprod`,`other_writ` )
VALUES
('$id','$native','$other','$other_list','$other_read','$other_spokint',
'$other_spokprod','$other_writ') ";
mysql_query($sql_insert, $link) or die("Insertion Failed:" . mysql_error());
}
header("Location: myaccount.php?id=' . $_SESSION[user_id] .'");
exit();
}
}
}
All is fine until , for example I register id=3 (in users table) and then log back into id=1 and change their details in the language table, then their user_id in the language table (which is foreign key to id in users table) is 3 when it should be 1. To make things simple, the id in users table should be same as the user_id in the language table. But when going back and changing data in the languages table the user_id stays the same as the last id that registered!
Please help!
This query you have:
$result = mysql_query("SELECT `id` FROM users WHERE `banned` = '0' order by id desc");
What is the purpose of it? You are assigning to $id the first value it finds, yet the query doesn't look for user name or anything else. You probably want to user $_SESSION['$user_id'] instead of $id as your user's ID.

Unable to relate two MySQL tables (foreign keys)

Here is my USER table
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(100) NOT NULL,
`expiry` varchar(6) NOT NULL,
`contact_id` int(11) NOT NULL,
`email` varchar(255) NOT NULL,
`password` varchar(100) NOT NULL,
`level` int(3) NOT NULL,
`active` tinyint(4) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`,`email`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
And here is my contact_info table
CREATE TABLE IF NOT EXISTS `contact_info` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`email_address` varchar(255) NOT NULL,
`company_name` varchar(255) NOT NULL,
`license_number` varchar(255) NOT NULL,
`phone` varchar(30) NOT NULL,
`fax` varchar(30) NOT NULL,
`mobile` varchar(30) NOT NULL,
`category` varchar(100) NOT NULL,
`country` varchar(20) NOT NULL,
`state` varchar(20) NOT NULL,
`city` varchar(100) NOT NULL,
`postcode` varchar(50) NOT NULL,
PRIMARY KEY (`id`,`email_address`),
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
The system uses username to login users. I want to modify it in such a way that it uses email for login. But there is no email_address in users table.
I have added foreign key - email in user table(which is email_address in contact_info).
How should I query database?
No, no, no, no no. Seriously, no. Don't make me come over there :-)
You're breaking third normal form by storing the email address twice.
The relationship need only be a short one, that of id. Assuming you're not guaranteeing the IDs will be identical in the two tables (i.e., my users.id isn't necessarily equal to my contact_info.id), just add a ci_id to the users table to act as a foreign key to the contact_info table.
Then the query to get a user's username and email will be something like:
select u.username, ci.email
from users u, contact_info ci
where u.username = 'paxdiablo'
and u.ci_id = ci.id;

Categories