A foreign key constraint fails with Zend_Db_Table - mysql

I have to tables and their SQL is as below:
CREATE TABLE item (
itemID INTEGER UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL,
name VARCHAR(100) NOT NULL,
price FLOAT NOT NULL,
stock INTEGER NOT NULL
) ENGINE = InnoDB;
CREATE TABLE salesrecord (
recordID INTEGER UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL,
itemID INT UNSIGNED NOT NULL,
recordDate DATE NOT NULL,
FOREIGN KEY (itemID) REFERENCES item (itemID)
) ENGINE = InnoDB;
And this is my Zend_Db_Table concrete classes:
<?php
class Store_Model_Items extends Zend_Db_Table_Abstract
{
protected $_name = 'item';
protected $_rowClass = 'Store_Model_Item';
protected $_dependTables = array('Store_Model_SalesRecords');
}
<?php
class Store_Model_SalesRecords extends Zend_Db_Table_Abstract
{
protected $_name = 'salesrecord';
protected $_referenceMap = array(
'Item' => array(
'columns' => array('itemID'),
'refTableClass' => 'Store_Model_Items',
'refColumns' => array('itemID'),
'onDelete' => self::CASCADE
)
);
}
When I try to delete a row in item table,
I get this message:
SQLSTATE[HY000]: General error: 1451 Cannot delete or update a parent row: a foreign key constraint fails (newstore/salesrecord, CONSTRAINT salesrecord_ibfk_1 FOREIGN KEY (itemID) REFERENCES item (itemID))

If you want delete the record from parent table, firstly you should delete related records in a child table. Also you can add ON DELETE CASCADE checking, it will help automatically delete related records in the child table. Try to recreate your FK in this way -
ALTER TABLE salesrecord
DROP FOREIGN KEY salesrecord_ibfk_1; -- change FK name here!
ALTER TABLE salesrecord
ADD CONSTRAINT salesrecord_ibfk_1 FOREIGN KEY (itemID)
REFERENCES item(itemID) ON DELETE CASCADE;
Change 'salesrecord_ibfk_1' with actual FK name.

Related

Laravel UUID as primary key and ID as foreign key

I've defined a uuid as primary key, and would like to use id (auto increment) as foreign key to define relationships.
Both Posts and Comments have in their migration:
$table->uuid('uuid')->primary();
$table->bigInteger('id');
Their models have:
protected $primaryKey = 'uuid';
protected $keyType = 'string';
public $incrementing = false;
And the comments migration has
$table->bigInteger('post_id')->unsigned();
$table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
But if I run the migration I get General error: 1215 Cannot add foreign key constraint (SQL: alter table `comments` add constraint `comments_post_id_foreign` foreign key (`post_id`) references `posts` (`id`) on delete cascade) of which I'm not sure why it's happening? Before adding the UUID logic it was working fine so I'm sure I've made a mistake there, but I'm not sure what as the error is generic.
Give this a try.
$table->foreignId('post_id')->constrained('posts')->onDelete('cascade');
Adding a foreign key requires the referenced key and the foreign one to have the same type and sign. According to your migrations, both posts.id and comments.id are signed bigints but you are trying to add a foreign key to a unsigned bigint.
In your migrations for posts and comments, change
$table->bigInteger('id');
to
$table->bigInteger('id')->unsigned();
and migrate them again.
You can try this.
$table->foreignUuid('post_id')->constrained()->onDelete('cascade');
You can have a look at the method which is inside the vendor/laravel/framework/src/Illuminate/Database/Schema/Blueprint.php
/**
* Create a new UUID column on the table with a foreign key constraint.
*
* #param string $column
* #return \Illuminate\Database\Schema\ForeignIdColumnDefinition
*/
public function foreignUuid($column)
{
return $this->columns[] = new ForeignIdColumnDefinition($this, [
'type' => 'uuid',
'name' => $column,
]);
}

Mysql composite key out of a foreign composite key

I'm trying to make a many-to-many relationship between two tables In Mysql WorkBench, and one of those 2 tables has a composite primary key ( parts are coming from 2 foreign keys). When I'm trying to generate the SQL I'm getting this error :
ERROR: Error 1215: Cannot add foreign key constraint
SQL Code:
-- -----------------------------------------------------
-- Table `A_D_schema`.`Resources_has_OwnerGroups`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `A_D_schema`.`Resources_has_OwnerGroups` (
`Resources_id` INT NOT NULL,
`OwnerGroups_id` INT NOT NULL,
`OwnerGroups_Instances_has_Customers_Instances_idInstances` INT NOT NULL,
`OwnerGroups_Instances_has_Customers_Customers_idCustomers` INT NOT NULL,
PRIMARY KEY (`Resources_id`, `OwnerGroups_id`, `OwnerGroups_Instances_has_Customers_Instances_idInstances`, `OwnerGroups_Instances_has_Customers_Customers_idCustomers`),
INDEX `fk_Resources_has_OwnerGroups_OwnerGroups1_idx` (`OwnerGroups_id` ASC, `OwnerGroups_Instances_has_Customers_Instances_idInstances` ASC, `OwnerGroups_Instances_has_Customers_Customers_idCustomers` ASC),
INDEX `fk_Resources_has_OwnerGroups_Resources1_idx` (`Resources_id` ASC),
CONSTRAINT `fk_Resources_has_OwnerGroups_Resources1`
FOREIGN KEY (`Resources_id`)
REFERENCES `A_D_schema`.`Resources` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_Resources_has_OwnerGroups_OwnerGroups1`
FOREIGN KEY (`OwnerGroups_id` , `OwnerGroups_Instances_has_Customers_Instances_idInstances` , `OwnerGroups_Instances_has_Customers_Customers_idCustomers`)
REFERENCES `A_D_schema`.`OwnerGroups` (`id` , `Instances_has_Customers_Instances_idInstances` , `Instances_has_Customers_Customers_idCustomers`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
From the SHOW ENGINE INNODB STATUS I can see this message :
Cannot resolve column name close to:
)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_Resources_has_OwnerGroups_OwnerGroups1`
FOREIGN KEY (`OwnerGroups_id` , `OwnerGroups_Instances_has_Customers_Instances_idInstances` , `OwnerGroups_Instances_has_Customers_Customers_idCustomers`)
REFERENCES `A_D_schema`.`OwnerGroups` (`id` , `Instances_has_Customers_Instances_idInstances` , `Instances_has_Customers_Customers_idCustomers`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
The SHOW CREATE TABLE Resources and SHOW CREATE TABLE OwnerGroups :
CREATE TABLE `Resources` (
`idResources` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(45) DEFAULT NULL,
`role` int(11) DEFAULT NULL COMMENT 'role : 1 disptcher \n0 admin',
PRIMARY KEY (`idResources`),
UNIQUE KEY `idresources_UNIQUE` (`idResources`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `OwnerGroups` (
`idOwnerGroups` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) DEFAULT NULL,
`group` int(11) DEFAULT NULL,
PRIMARY KEY (`idOwnerGroups`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CONSTRAINT `fk_Resources_has_OwnerGroups_Resources1`
FOREIGN KEY (`Resources_id`)
REFERENCES `A_D_schema`.`Resources` (`id`)
Your Resources table doesn't have a column id. Its primary key is idResources.
CONSTRAINT `fk_Resources_has_OwnerGroups_OwnerGroups1`
FOREIGN KEY (`OwnerGroups_id` , `OwnerGroups_Instances_has_Customers_Instances_idInstances` , `OwnerGroups_Instances_has_Customers_Customers_idCustomers`)
REFERENCES `A_D_schema`.`OwnerGroups` (`id` , `Instances_has_Customers_Instances_idInstances` , `Instances_has_Customers_Customers_idCustomers`)
Your OwnerGroups table doesn't have a column id. Its primary key is idOwnerGroups. It doesn't have the other two columns you reference at all.
In general, when you declare a foreign key, first you name the columns in the child table:
CREATE TABLE Child (
childCol1 INT,
childCol2 INT,
...
FOREIGN KEY (childCol1, childCol2) ...
Then you reference columns in the parent table:
... REFERENCES Parent (parentCol1, parentCol2)
);
You must use the names of columns as they exist in the parent table.
The columns you reference in the parent table must together be the PRIMARY KEY or UNIQUE KEY of that table. In other words, given the example above, it would not work against this Parent table:
CREATE TABLE Parent (
parentCol1 INT,
parentCol2 INT,
PRIMARY KEY (parentCol1)
);
Because the PRIMARY KEY does not include parentCol2.
In your case, the following should work:
CREATE TABLE IF NOT EXISTS `A_D_schema`.`Resources_has_OwnerGroups` (
`Resources_id` INT NOT NULL,
`OwnerGroups_id` INT NOT NULL,
`OwnerGroups_Instances_has_Customers_Instances_idInstances` INT NOT NULL,
`OwnerGroups_Instances_has_Customers_Customers_idCustomers` INT NOT NULL,
PRIMARY KEY (`Resources_id`, `OwnerGroups_id`, `OwnerGroups_Instances_has_Customers_Instances_idInstances`, `OwnerGroups_Instances_has_Customers_Customers_idCustomers`),
CONSTRAINT `fk_Resources_has_OwnerGroups_Resources1`
FOREIGN KEY (`Resources_id`)
REFERENCES `A_D_schema`.`Resources` (`idResources`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_Resources_has_OwnerGroups_OwnerGroups1`
FOREIGN KEY (`OwnerGroups_id`)
REFERENCES `A_D_schema`.`OwnerGroups` (`idOwnerGroups`)
ON DELETE NO ACTION
ON UPDATE NO ACTION
) ENGINE = InnoDB
I took out a couple of INDEX definitions that are redundant. You don't need to index your PRIMARY KEY, it's already the clustered index of the table. You don't need to index the column you use in a foreign key declaration, MySQL will index that column automatically if it need to (though if an index already exists for that column, the FK constraint will use that index).
I'm not sure I understand what your other two columns OwnerGroups_Instances_has_Customers_Instances_idInstances and OwnerGroups_Instances_has_Customers_Customers_idCustomers are meant to do. Typically in a many-to-many table, you only need enough columns to reference the primary keys of the respective parent tables.
Re your comment:
You should try refreshing the view of the schema from time to time. There's a button with a pair of curvy arrows, to the right of "SCHEMAS".

How to Link Foreign Key with Different Name

I have 2 different tables: Profile and Transaction
Profile consists of: pID, firstName, lastName, phoneNumb
Transaction consists of: transID, sellerID, buyerID, itemID
My question is:
How to make sure that both sellerID and buyerID act as a foreign key in reference to profileID in Profile table?
My current code right now:
CREATE TABLE PROFILE
(
pID INT NOT NULL AUTO_INCREMENT ,
firstName VARCHAR(20) NOT NULL ,
lastName INT(20) NOT NULL ,
phoneNumb INT NOT NULL ,
PRIMARY KEY (pID)
) ENGINE = InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE TRANSACTION
(
tID INT NOT NULL AUTO_INCREMENT ,
sellerID INT ,
buyerID INT,
itemID INT,
PRIMARY KEY (tID),
FOREIGN KEY (sellerID, buyerID) REFERENCES PROFILE(pID),
FOREIGN KEY (itemID) REFERENCES ITEM (itemID)
) ENGINE = InnoDB DEFAULT CHARSET=latin1;
I tried this and it gave me this kind of error
1239 - Incorrect foreign key definition for 'foreign key without name': Key reference and table reference don't match
Thanks.
I would go about it this way:
CREATE TABLE TRANSACTION
(
tID INT NOT NULL AUTO_INCREMENT,
sellerID INT,
buyerID INT,
itemID INT,
PRIMARY KEY (tID),
CONSTRAINT fk1 FOREIGN KEY (sellerID) REFERENCES PROFILE(pID)
CONSTRAINT fk2 FOREIGN KEY (buyerID) REFERENCES PROFILE(pID)
CONSTRAINT itemKey FOREIGN KEY (itemID) REFERENCES ITEM (itemID)
) ENGINE = InnoDB DEFAULT CHARSET=latin1;
This assumes that a table called ITEM exists which has a primary key called itemID. Your original problem mentioned only two tables. If ITEM does not exist, then either create it or remove the foreign key constraint from TRANSACTION.

Create Foreign Key in Mysql have error Cannot resolve table name close to

I have trouble in adding a foreign key. I have the following script:
CREATE DATABASE IF NOT EXISTS dbdemo;
use dbdemo;
CREATE TABLE categories(
cat_id int unsigned not null auto_increment primary key,
cat_name varchar(255) not null,
cat_description text
) ENGINE=InnoDB;
CREATE TABLE products(
prd_id int unsigned not null auto_increment primary key,
prd_name varchar(355) not null,
prd_price decimal,
cat_id int unsigned not null,
constraint fk_cat
FOREIGN KEY fk_cat( cat_id )
REFERENCES categories( cat_id )
ON UPDATE cascade
ON DELETE RESTRICT
) ENGINE=InnoDB;
CREATE TABLE vendors(
vdr_id int unsigned not null auto_increment primary key,
vdr_name varchar(255)
) ENGINE=InnoDB;
ALTER TABLE products
ADD COLUMN prod_vdr_id int unsigned not null;
Then I got error when I try to add a FOREIGN KEY :
ALTER TABLE products
ADD FOREIGN KEY fk_vendor(prod_vdr_id)
REFERENCES vendor(vdr_id)
ON UPDATE CASCADE
ON DELETE NO ACTION;
Then I got this error:
Error Code: 1005. Can't create table 'dbdemo.#sql-565_35' (errno: 150)
If i run "Show Engine innodb status;" I got :
------------------------
LATEST FOREIGN KEY ERROR
------------------------
150430 15:30:00 Error in foreign key constraint of table dbdemo/#sql-565_35:
FOREIGN KEY fk_vendor(prod_vdr_id)
REFERENCES vendor(vdr_id)
ON UPDATE CASCADE
ON DELETE NO ACTION:
Cannot resolve table name close to:
(vdr_id)
ON UPDATE CASCADE
ON DELETE NO ACTION
Can anyone show me some light where went wrong?
TQVM
It is VENDORS not VENDOR
ALTER TABLE products
ADD FOREIGN KEY fk_vendor(prod_vdr_id)
REFERENCES vendors(vdr_id)
ON UPDATE CASCADE
ON DELETE NO ACTION;

Getting a "foreign key constraint fails" even though I have "on delete cascade"

I thought the point of ON DELETE CASCADE was that this wouldn't happen. :\ I have the following tables:
CREATE TABLE Tweets (
tweetID INTEGER NOT NULL AUTO_INCREMENT,
userID INTEGER NOT NULL,
content VARCHAR(140) NOT NULL,
dateTime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
hasPoll INTEGER NOT NULL,
visible INTEGER NOT NULL DEFAULT 1,
PRIMARY KEY (tweetID),
FOREIGN KEY (userID) REFERENCES Users(userID)
ON DELETE CASCADE
);
CREATE TABLE Polls (
pollID INTEGER NOT NULL AUTO_INCREMENT,
tweetID INTEGER NOT NULL,
pollOptionText VARCHAR(300),
PRIMARY KEY (pollID),
FOREIGN KEY (tweetID) REFERENCES Tweets(tweetID)
);
The problem is that when I try to delete a Tweet which has a Poll attached to it, I get the following error (via Flask):
_mysql_exceptions.IntegrityError
IntegrityError: (1451, 'Cannot delete or update a parent row: a foreign key constraint fails (`twitter`.`polls`, CONSTRAINT `polls_ibfk_1` FOREIGN KEY (`tweetID`) REFERENCES `Tweets` (`tweetID`))')
Help please!
That is indeed the point of on delete cascade. You get the error, because your code doesn't declare on delete cascade from "poll" to "tweet".
CREATE TABLE Polls (
pollID INTEGER NOT NULL AUTO_INCREMENT,
tweetID INTEGER NOT NULL,
pollOptionText VARCHAR(300),
PRIMARY KEY (pollID),
FOREIGN KEY (tweetID) REFERENCES Tweets(tweetID)
ON DELETE CASCADE
);
This will delete rows in "Polls" when corresponding rows are deleted in "Tweets".
You have to put ON DELETE CASCADE after FOREIGN KEY (tweetID) REFERENCES Tweets(tweetID)
According to the MySQL Foreign Key Constraints reference:
CASCADE: Delete or update the row from the parent table, and
automatically delete or update the matching rows in the child table.
Both ON DELETE CASCADE and ON UPDATE CASCADE are supported.
Also, according to the MySQL Foreign Keys reference:
For storage engines other than InnoDB, it is possible when defining a
column to use a REFERENCES tbl_name(col_name) clause, which has no
actual effect, and serves only as a memo or comment to you that the
column which you are currently defining is intended to refer to a
column in another table.
So since the foreign key is from the child table to the parent table, it makes foo a parent table and Polls a child table, so deleting a row from Tweets will cascade deletions to Pools, providing you use InnoDB or some other storage engine that supports it.
UPDATE:
This error is because you have a relation between poll and twitter... without cascading you have to delete or update the polls removing the relation with the Tweet that will be deleted. Or use ON DELETE CASCADE:
CREATE TABLE Tweets (
tweetID INTEGER NOT NULL AUTO_INCREMENT,
content VARCHAR(140) NOT NULL,
PRIMARY KEY (tweetID)
);
CREATE TABLE Polls (
pollID INTEGER NOT NULL AUTO_INCREMENT,
tweetID INTEGER NOT NULL,
pollOptionText VARCHAR(300),
PRIMARY KEY (pollID),
FOREIGN KEY (tweetID) REFERENCES Tweets(tweetID)
ON DELETE CASCADE
);
INSERT INTO Tweets VALUES(1,'tweet');
INSERT INTO Polls VALUES(1,1,"pool");
DELETE FROM Tweets WHERE tweetID = 1;
You will surely get this error. you have to keep at least one record into tweets.