Problem creating a table using php - php

I am trying to create a table in MySql using php. My code looks like this:
$sql = "CREATE TABLE qotwQuestion1111
(
QuestionId int PRIMARY KEY AUTOINCREMENT,
Question varchar(5000),
MemberId varchar(255) FOREIGN KEY REFERENCES qotwMember(MemberId),
PostDate date,
Vote int
)";
mysql_query($sql,$con);
i am unable to create this table, the error is in the "AUTOINCREMENT" and also the "FOREIGN KEY" ..
Can someone tell me what am i doing wrong here. and what should i do to solve this problem please
Best
Zeeshan

http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html
The keyword is AUTO INCREMENT
http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html
foreign keys are specified as constraints or by FOREIGN KEY fk_name REFERENCES table(key) .
When you have a problem with your sql syntax, it tells you to check your sql manual near where the error occurred. I suggest you take its advice.

Related

SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint laravel 5.6.5 [duplicate]

I am trying to create a table in MySQL with two foreign keys, which reference the primary keys in 2 other tables, but I am getting an errno: 150 error and it will not create the table.
Here is the SQL for all 3 tables:
CREATE TABLE role_groups (
`role_group_id` int(11) NOT NULL `AUTO_INCREMENT`,
`name` varchar(20),
`description` varchar(200),
PRIMARY KEY (`role_group_id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `roles` (
`role_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50),
`description` varchar(200),
PRIMARY KEY (`role_id`)
) ENGINE=InnoDB;
create table role_map (
`role_map_id` int not null `auto_increment`,
`role_id` int not null,
`role_group_id` int not null,
primary key(`role_map_id`),
foreign key(`role_id`) references roles(`role_id`),
foreign key(`role_group_id`) references role_groups(`role_group_id`)
) engine=InnoDB;
These conditions must be satisfied to not get error 150 re ALTER TABLE ADD FOREIGN KEY:
The Parent table must exist before you define a foreign key to reference it. You must define the tables in the right order: Parent table first, then the Child table. If both tables references each other, you must create one table without FK constraints, then create the second table, then add the FK constraint to the first table with ALTER TABLE.
The two tables must both support foreign key constraints, i.e. ENGINE=InnoDB. Other storage engines silently ignore foreign key definitions, so they return no error or warning, but the FK constraint is not saved.
The referenced columns in the Parent table must be the left-most columns of a key. Best if the key in the Parent is PRIMARY KEY or UNIQUE KEY.
The FK definition must reference the PK column(s) in the same order as the PK definition. For example, if the FK REFERENCES Parent(a,b,c) then the Parent's PK must not be defined on columns in order (a,c,b).
The PK column(s) in the Parent table must be the same data type as the FK column(s) in the Child table. For example, if a PK column in the Parent table is UNSIGNED, be sure to define UNSIGNED for the corresponding column in the Child table field.
Exception: length of strings may be different. For example, VARCHAR(10) can reference VARCHAR(20) or vice versa.
Any string-type FK column(s) must have the same character set and collation as the corresponding PK column(s).
If there is data already in the Child table, every value in the FK column(s) must match a value in the Parent table PK column(s). Check this with a query like:
SELECT COUNT(*) FROM Child LEFT OUTER JOIN Parent ON Child.FK = Parent.PK
WHERE Parent.PK IS NULL;
This must return zero (0) unmatched values. Obviously, this query is an generic example; you must substitute your table names and column names.
Neither the Parent table nor the Child table can be a TEMPORARY table.
Neither the Parent table nor the Child table can be a PARTITIONED table.
If you declare a FK with the ON DELETE SET NULL option, then the FK column(s) must be nullable.
If you declare a constraint name for a foreign key, the constraint name must be unique in the whole schema, not only in the table in which the constraint is defined. Two tables may not have their own constraint with the same name.
If there are any other FK's in other tables pointing at the same field you are attempting to create the new FK for, and they are malformed (i.e. different collation), they will need to be made consistent first. This may be a result of past changes where SET FOREIGN_KEY_CHECKS = 0; was utilized with an inconsistent relationship defined by mistake. See #andrewdotn's answer below for instructions on how to identify these problem FK's.
MySQL’s generic “errno 150” message “means that a foreign key constraint was not correctly formed.” As you probably already know if you are reading this page, the generic “errno: 150” error message is really unhelpful. However:
You can get the actual error message by running SHOW ENGINE INNODB STATUS; and then looking for LATEST FOREIGN KEY ERROR in the output.
For example, this attempt to create a foreign key constraint:
CREATE TABLE t1
(id INTEGER);
CREATE TABLE t2
(t1_id INTEGER,
CONSTRAINT FOREIGN KEY (t1_id) REFERENCES t1 (id));
fails with the error Can't create table 'test.t2' (errno: 150). That doesn’t tell anyone anything useful other than that it’s a foreign key problem. But run SHOW ENGINE INNODB STATUS; and it will say:
------------------------
LATEST FOREIGN KEY ERROR
------------------------
130811 23:36:38 Error in foreign key constraint of table test/t2:
FOREIGN KEY (t1_id) REFERENCES t1 (id)):
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
It says that the problem is it can’t find an index. SHOW INDEX FROM t1 shows that there aren’t any indexes at all for table t1. Fix that by, say, defining a primary key on t1, and the foreign key constraint will be created successfully.
Make sure that the properties of the two fields you are trying to link with a constraint are exactly the same.
Often, the 'unsigned' property on an ID column will catch you out.
ALTER TABLE `dbname`.`tablename` CHANGE `fieldname` `fieldname` int(10) UNSIGNED NULL;
What's the current state of your database when you run this script? Is it completely empty? Your SQL runs fine for me when creating a database from scratch, but errno 150 usually has to do with dropping & recreating tables that are part of a foreign key. I'm getting the feeling you're not working with a 100% fresh and new database.
If you're erroring out when "source"-ing your SQL file, you should be able to run the command "SHOW ENGINE INNODB STATUS" from the MySQL prompt immediately after the "source" command to see more detailed error info.
You may want to check out the manual entry too:
If you re-create a table that was dropped, it must have a definition that conforms to the foreign key constraints referencing it. It must have the right column names and types, and it must have indexes on the referenced keys, as stated earlier. If these are not satisfied, MySQL returns error number 1005 and refers to error 150 in the error message. If MySQL reports an error number 1005 from a CREATE TABLE statement, and the error message refers to error 150, table creation failed because a foreign key constraint was not correctly formed.
— MySQL 5.1 reference manual.
For people who are viewing this thread with the same problem:
There are a lot of reasons for getting errors like this. For a fairly complete list of causes and solutions of foreign key errors in MySQL (including those discussed here), check out this link:
MySQL Foreign Key Errors and Errno 150
For others that find this SO entry via Google: Be sure that you aren't trying to do a SET NULL action on a foreign key (to be) column defined as "NOT NULL." That caused great frustration until I remembered to do a CHECK ENGINE INNODB STATUS.
Definitely it is not the case but I found this mistake pretty common and unobvious. The target of a FOREIGN KEY could be not PRIMARY KEY. Te answer which become useful for me is:
A FOREIGN KEY always must be pointed to a PRIMARY KEY true field of other table.
CREATE TABLE users(
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(40));
CREATE TABLE userroles(
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
FOREIGN KEY(user_id) REFERENCES users(id));
As pointed by #andrewdotn the best way is to see the detailed error(SHOW ENGINE INNODB STATUS;) instead of just an error code.
One of the reasons could be that an index already exists with the same name, may be in another table. As a practice, I recommend prefixing table name before the index name to avoid such collisions. e.g. instead of idx_userId use idx_userActionMapping_userId.
Please make sure at first that
you are using InnoDB tables.
field for FOREIGN KEY has the same type and length (!) as source field.
I had the same trouble and I've fixed it. I had unsigned INT for one field and just integer for other field.
Helpful tip, use SHOW WARNINGS; after trying your CREATE query and you will receive the error as well as the more detailed warning:
---------------------------------------------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+-------------------------------------------------------------------------- -------------------------------------------------------------------------------------------- ---------------+
| Warning | 150 | Create table 'fakeDatabase/exampleTable' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns.
|
| Error | 1005 | Can't create table 'exampleTable' (errno:150) |
+---------+------+-------------------------------------------------------------------------- -------------------------------------------------------------------------------------------- ---------------+
So in this case, time to re-create my table!
This is usually happening when you try to source file into existing database.
Drop all the tables first (or the DB itself).
And then source file with SET foreign_key_checks = 0; at the beginning and SET foreign_key_checks = 1; at the end.
I've found another reason this fails... case sensitive table names.
For this table definition
CREATE TABLE user (
userId int PRIMARY KEY AUTO_INCREMENT,
username varchar(30) NOT NULL
) ENGINE=InnoDB;
This table definition works
CREATE TABLE product (
id int PRIMARY KEY AUTO_INCREMENT,
userId int,
FOREIGN KEY fkProductUser1(userId) REFERENCES **u**ser(userId)
) ENGINE=InnoDB;
whereas this one fails
CREATE TABLE product (
id int PRIMARY KEY AUTO_INCREMENT,
userId int,
FOREIGN KEY fkProductUser1(userId) REFERENCES User(userId)
) ENGINE=InnoDB;
The fact that it worked on Windows and failed on Unix took me a couple of hours to figure out. Hope that helps someone else.
MySQL Workbench 6.3 for Mac OS.
Problem: errno 150 on table X when trying to do Forward Engineering on a DB diagram, 20 out of 21 succeeded, 1 failed. If FKs on table X were deleted, the error moved to a different table that wasn't failing before.
Changed all tables engine to myISAM and it worked just fine.
Also worth checking that you aren't accidentally operating on the wrong database. This error will occur if the foreign table does not exist. Why does MySQL have to be so cryptic?
Make sure that the foreign keys are not listed as unique in the parent. I had this same problem and I solved it by demarcating it as not unique.
In my case it was due to the fact that the field that was a foreign key field had a too long name, ie. foreign key (some_other_table_with_long_name_id). Try sth shorter. Error message is a bit misleading in that case.
Also, as #Jon mentioned earlier - field definitions have to be the same (watch out for unsigned subtype).
(Side notes too big for a Comment)
There is no need for an AUTO_INCREMENT id in a mapping table; get rid of it.
Change the PRIMARY KEY to (role_id, role_group_id) (in either order). This will make accesses faster.
Since you probably want to map both directions, also add an INDEX with those two columns in the opposite order. (There is no need to make it UNIQUE.)
More tips: http://mysql.rjweb.org/doc.php/index_cookbook_mysql#speeding_up_wp_postmeta
When the foreign key constraint is based on varchar type, then in addition to the list provided by marv-el the target column must have an unique constraint.
execute below line before creating table :
SET FOREIGN_KEY_CHECKS = 0;
FOREIGN_KEY_CHECKS option specifies whether or not to check foreign key constraints for InnoDB tables.
-- Specify to check foreign key constraints (this is the default)
SET FOREIGN_KEY_CHECKS = 1;
 
-- Do not check foreign key constraints
SET FOREIGN_KEY_CHECKS = 0;
When to Use :
Temporarily disabling referential constraints (set FOREIGN_KEY_CHECKS to 0) is useful when you need to re-create the tables and load data in any parent-child order
I encountered the same problem, but I check find that I hadn't the parent table. So I just edit the parent migration in front of the child migration. Just do it.

Inserting into mysql table using foreign key with PHP

Hi I have two tables,
users_table and orders table.
users_id is in both tables
as a primary key in users_table and as foreign key in orders_table(referencing users_id in users_table)
When I try to place an order if it's the first time the user is able to place an order but if a user already placed an order the data is not saved to the database in the second attempt.. any Idea why? or any solutions?
I apologise for the bad english
MY PHP CODE:
$query = "INSERT INTO orders_table(users_id, orders_postDate, orders_category, orders_categoryId, orders_name, orders_description, orders_deliveryDate) VALUES('$users_id', '$orders_postDate', '$orders_category', '$orders_categoryId', '$orders_name', '$orders_description', '$orders_deliveryDate')";
$result = mysqli_query($connection, $query);
if($result){
echo "SUCCESS";
}else{
echo "fail";
}
so Let's say that I created an account, signed in and placed an order, the data is successfully on the database. if I try to place a new order with the same user I get the fail message.. so for some reason
mysqli_query($connection, $query);
fails the second time, I am assuming that it is because my foreign key is a primary key? how can I fix this?
Without code/error message it is difficult to say what the issue is. However, you mentioned that user_id is the foreign key for the orders_table, but if it is also used for the primary key for your orders_table it would cause duplication when creating any subsequent orders, hence, insertion of a new order would fail.
These might help you to help us to get a better understanding of whats going on.
How is your orders_table created?
What is the primary key for Orders_table?
How do you assign the primary key (if you do) upon insertion of a new record?
Since you are able to insert the first record that means you get a successful connection. So instead of echoing "success" and "fail", extract the mysqli error instead.
Also, since you are dealing with MySQL and PHP you might want to take a look into using PDO objects instead, if you haven't already. Being able to use prepared statements is a huge plus.
Yes, you are right, if orders_table.user_id with primary key, also there is a 'unique' key. If so, MySql did not allow to paste the same user_id.
Use ALTER TABLE sql command to remove the primary key on orders_table.user_id add add a new column with primary key.
There is code you need:
ALTER TABLE orders_table DROP PRIMARY KEY;
ALTER TABLE orders_table ADD COLUMN `id` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE orders_table ADD PRIMARY KEY(`id`);
Your insert query is not getting data from the users_table and so will not be able to insert the right user data into the Orders_table; and second, the order_table is created having user_id as a primary key and foreign key which will cause data duplication. Try altering the table to drop the primary and create another column for it(Primary key).
An example
ALTER TABLE orders_table DROP PRIMARY KEY;
ALTER TABLE orders_table ADD COLUMN 'id' int NOT NULL AUTO_INCREMENT PRIMARY KEY;
That should make your code work now.

Alter Table gives error #1064 [duplicate]

This question already has an answer here:
Syntax error due to using a reserved word as a table or column name in MySQL
(1 answer)
Closed 8 years ago.
I am trying to create two tables in phpmyadmin: Users and Keys, the schema is as follows:
Users:
id int auto_incerement primary key
name varchar(50) not null
Keys:
user_id int
keys varchar(50) not null
Now I am running the following query to make the user_id in Keys a foreign key referencing the id in Users
ALTER TABLE Keys
FOREIGN KEY(user_id) REFERENCES Users(id)
ON UPDATE CASCADE
ON DELETE CASCADE
But after executing, i am getting the following error:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Keys FOREIGN KEY(user_id) REFERENCES Users(id) ON UPDATE CASCADE ON DELETE CA' at line 1
Can anyone tell me what am I doing wrong?
Thanks in advance.
Keys is a reserved word and must be encased in backticks:
ALTER TABLE `Keys`
ADD FOREIGN KEY (user_id) REFERENCES `Users` (`id`)
ON UPDATE CASCADE
ON DELETE CASCADE
It's best practice to encase all system related words in backticks.
KEYS is a reserved keyword. See also: http://dev.mysql.com/doc/refman/5.5/en/reserved-words.html
You need to wrap them in backticks:
ALTER TABLE `Keys`
...
You need to enclose keys with back tick.
ALTER TABLE `Keys`

Connecting One table to Many tables

I am building a commenting system where people can comment on uploaded files, messages and to-do items. What is the best way to connect the comment table table to the other various tables?
Possible Solutions
Solution one - use a two field foreign key.
CREATE TABLE `comments`(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
foreign_key INT NOT NULL,
table_name enum('files','messages','to-do'),
user_id INT NOT NULL,
comment TEXT NOT NULL);
Solution two - Each table would have a primary key unique to the database. So I would use php's uniqid($prefix) as the primary keys for each table.
CREATE TABLE `comments`(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
foreign_key char(23) NOT NULL,
table_name enum('files','messages','to-do'),
user_id INT NOT NULL,
comment TEXT NOT NULL);
Solution Three - Have multiple foreign keys in the comment table
CREATE TABLE `comments`(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
files_id INT NOT NULL,
messages_id INT NOT NULL,
to_do_id INT NOT NULL,
user_id INT NOT NULL,
comment TEXT NOT NULL);
What is the best solution? I appreciate your input and please let me know if I can clarify anything
EDIT removed table_name from solution three as it was a copy_paste error
As to Joe's Response
Assume:
1) all data is already escaped. Do we really need to see that?
2) $fileId = "146".
3) $userId = "432".
4) $comment = "Stackoverflow is so awesome!"
INSERT
$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
if (!$link) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db('mydb');
mysql_query("INSERT INTO `comments` (user_id,comment) VALUES($userId,$comment)");
$commentId = mysql_insert_id();
mysql_query("INSERT INTO `comments_files_xref` (file_id,comment_id) VALUES($fileId,$commentId)");
Personally, I would normalize the design a bit more. Perhaps something like:
Multiple remarks :
You shouldn't call your foreign key foreign_key because a foreign key is a constraint, not a field in a way. it references a field in a table to an index on another, call it the same way you called the PK on the table you reference, or something recognizable.
Foreign keys constraints only works on innodb, if you use MyISAM forget about them and do a lot of checks with PHP.
read http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html
You should make a sketch of what you want in your DB or use tools like mysql workbench (which is free) that helps seeing the schema better.
As I see your problem and if you want to use constraint here, I'll use solution one or another solution :
1-
CREATE TABLE `comments`(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, // Which is your comment index
idTable INT NOT NULL, // ID of the message
table_name enum('files','messages','to-do'), // which it comes from
user_id INT NOT NULL, // etc...
comment TEXT NOT NULL);
But there are conditions :
The PK of files, messages _to-do_ must have the same format (INT)
If you want to add a module (to files, messages _to-do_) it'll be difficult
2-
Create tables joining comments and other tables :
CREATE TABLE `comments`(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, // Which is your comment index
user_id INT NOT NULL, // etc...
comment TEXT NOT NULL);
CREATE TABLE `comments-files`(
id_comments INT NOT NULL PRIMARY KEY,
id_files INT NOT NULL PRIMARY KEY);
etc. Hope you see the point here. You add constraint thanks to http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html if needed.
I just learn Ruby on Rails in my current company, and solution 1 is preferred because RoR's Active Record can handle it as polymorphic relation.
Back to the topic, that you are using PHP, I prefer either solution 1 or 3. Solution 1 is preferable if there are possibilities that the comment table will be used for other table in the future.
One note, in solution 3, I think the table_name column is not needed. You can determine for which table the comment is by fill either files_id, messages_id, or to_do_id with the id, then set 2 other foreign key with 0.
I would create a join table for each thing that can be commented on, so an files_comments table and a todo_comments table. But solution 1 would be an alternative. I would avoid solutions two or three... could get messy if things change in the future.

Problem creating a reference table in mysql using php

I am creating a two MySQL tables in PHP, using the code as given below:
$sql = "CREATE TABLE qotwMember
(
MemberId NOT NULL PRIMARY KEY,
Name varchar(255),
Passwork varchar(255),
emailId varchar(255),
)";
$sql = "CREATE TABLE qotwQuestion1111
(
QuestionId NOT NULL AUTO_INCREMENT,
Question varchar(5000),
MemberId varchar(255) FOREIGN KEY fkname REFERENCES qotwMember(MemberId),
PostDate date,
Vote int,
PRIMARY KEY (QuestionId)
)";
mysql_query($sql,$con);
Then i try to insert data into these tables. In the qotwMember table, the data gets entered, but when I try to insert data into the qotwQuestion1111 table, it gives me the error "Error: Table 'database1.qotwQuestion1111' doesn't exist"
I can not figure out what I am doing wrong here. Please help me with this problem.
Note: Both the tables have been created in a different php.
Regards
Zeeshan
Are you sure you are selecting the right database each time? See: mysql_select_db()
I suspect you're not giving us the real SQL because neither of those statements will actually work - you're missing the datatype for the primary column and have some extra commas.
If that is your real SQL, then make sure you put or die(mysql_error($con)); after calls to mysql_query
When you are creating your tables, it is probably easier to use a MySQL front end such as MySQL query browser instead of trying to run the CREATE TABLE statements inside PHP. My guess is there is a syntax error in your second statement, so the table is not getting created. The front end will show you what the syntax error is.
Alternatively, you could check the return value of mysql_query to see if there is an error, and then use mysql_error() to read it out.
I have had the same problem as you with foreign key creation in MySQL (which is what your error is about).
When creating foreign keys, both the foreign key column and the reference column must be of the same data type and size. I noticed you did not give your primary key column any datatype or size. This is probably what is causing your error. Also, as others have pointed out, what engine you are using also will dictate if you can use foreign keys.
If you declare 'MemberID' as 'MemberID varchar(255) NOT NULL PRIMARY KEY' it should work as you have it now. I would suggest always giving your primary key columns a datatype and possible size. I don't know what your tables are for, but for a primary key column that is just an ID, i would recommend making it an INT of some sort (just remember to change your foreign key column to reflect that change).

Categories