I created two tables in a database on MariaDB: CasaProduzione and Produzione.
create table CasaProduzione(nome varchar(80) primary key);
alter table CasaProduzione add column id tinyint;
alter table CasaProduzione drop primary key;
alter table CasaProduzione modify nome varchar(80) not null;
alter table CasaProduzione modify id tinyint primary key auto_increment;
create table Produzione(
id_film smallint not null,
id_casaProduzione tinyint not null,
data date not null,
constraint `fk_produzione`
foreign key (id_film) references Film(id),
foreign key (id_casaProduzione) references CasaProduzione(id)
on update cascade
on delete restrict);
alter table Produzione modify data in smallint(4);
After i moved the column id in the table of CasaProduzione at first
alter table CasaProduzione modify column id tinyint(4) first;
Then i tried to set auto_increment in prevoius column
alter table Produzione modify column id tinyint(4) auto_increment;
ERROR 1833 (HY000): Cannot change column 'id': used in a foreign key constraint 'Produzione_ibfk_1' of table 'Film.Produzione'
So i tried to cancel the foreign key from Produzione
alter table Produzione drop foreign key fk_produzione;
but the result is the same.
What am I doing wrong?
After suggestion from the comment, I post here the result of this command:
SHOW CREATE TABLE Film.Produzione \G;
***************************
1. row
***************************
Table: Produzione
Create Table:
CREATE TABLE Produzione (
id_film SMALLINT(6) NOT NULL,
id_casaProduzione TINYINT(4) NOT NULL,
DATA SMALLINT(4) DEFAULT NULL,
KEY fk_produzione (id_film),
KEY id_casaProduzione (id_casaProduzione),
CONSTRAINT Produzione_ibfk_1 FOREIGN KEY (id_casaProduzione) REFERENCES CasaProduzione (id) ON UPDATE CASCADE )
ENGINE=INNODB DEFAULT CHARSET=utf8mb4
1 row in set (0.001 sec)
As told by #FanoFN, with the command
show CREATE TABLE Film.Produzione \G;
the system showed me the constraint on the table Produzione. The system created the constraint Produzione_ibfk_1
I deleted this constraint with the command
alter table Produzione drop foreign key Produzione_ibfk_1;
Query OK, 0 rows affected (0.130 sec)
Records: 0 Duplicates: 0 Warnings: 0
After I can applied the command
alter table Produzione modify column id tinyint(4) auto_increment;
Thanks a lot
Related
I have table my_transitions and I am trying to delete field called myStage.
I am using this command:
alter table `my_transitions` drop `myStage`
I am seeing this error:
Key column 'myStage' doesn't exist in table
But when I list all fields using this command:
describe my_transitions
I can see
id bigint(20) unsigned NO PRI NULL auto_increment
myStage varchar(255) NO MUL NULL
updated_at timestamp YES NULL
Anyone can see if I am doing something wrong?
EDIT:
If I run show create table my_transitions;, I am getting:
CREATE TABLE `my_transitions` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`myStage` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`myStage1` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_stage_combination` (`myStage`,`myStage1`),
KEY `my_transitions_myStage` (`myStage`),
KEY `my_transitions_myStage1` (`myStage1`)
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
I have solved it by first deleting the unique key
ALTER TABLE my_transitions DROP INDEX unique_stage_combination;
It seems like it is not possible to delete a column if it is a part of index key in Maria DB 10.5.8.
This is a pecular bug in MariaDB. It affects MariaDB 10.5.
Demo: https://dbfiddle.uk/?rdbms=mariadb_10.5&fiddle=867204670347fa29e40bd5eb510c6956
The workaround is to drop the UNIQUE KEY that column mystage is part of first, then drop the column.
alter table my_transitions drop key unique_stage_combination, drop column mystage;
P.S.: I tested this on MySQL 8.0 and it does not require the workaround. It does drop the column, but it leaves the table with a UNIQUE KEY column on just one column mystage1, which might not be what you want.
The Alembic migration for a SQLite database:
def upgrade():
with op.batch_alter_table('my_table') as batch_op:
batch_op.add_column(sa.Column('parent_id', sa.String(24)))
batch_op.create_foreign_key('parent_constraint', 'my_table', ['parent_id'], ['id'])
which is supposed to create a foreign key parent_id referencing id of the same table my_table, creates a reference to a table called _alembic_batch_temp:
CREATE TABLE "my_table" (
id VARCHAR(24) NOT NULL,
parent_id VARCHAR(24),
PRIMARY KEY (id),
CONSTRAINT parent_constraint FOREIGN KEY(parent_id) REFERENCES _alembic_batch_temp (id)
)
How to create self-referencing constraints when altering a table?
After some research I found that the problem here is the way Alembic does the batch migration. In short, at the current version (0.7.6) of Alembic it's not possible to create relation with self by migration.
As described in the Alembic documentation, to do the migration, new table is created with a temporary name and changes from the alter table
code. In this case:
CREATE TABLE _alembic_batch_temp (
id VARCHAR(24) NOT NULL,
parent_id VARCHAR(24),
PRIMARY KEY (id),
CONSTRAINT parent_constraint FOREIGN KEY(parent_id) REFERENCES _alembic_batch_temp (id)
)
The table is filled with the data from the old table:
INSERT INTO _alembic_batch_temp (id) SELECT id FROM my_table;
Then the old table is removed:
DROP TABLE my_table;
Finally the newly created table is renamed to it's proper name:
ALTER TABLE _alembic_batch_temp RENAME TO my_table;
The problem with this way of doing things is already visible in the first code snippet. The newly created foreign key is referencing the temporary table and once it's created it can't be changed due to restrictions in SQLite. So after the renaming of the table you end up with the table you provided:
CREATE TABLE "my_table" ( # new name
id VARCHAR(24) NOT NULL,
parent_id VARCHAR(24),
PRIMARY KEY (id),
CONSTRAINT parent_constraint FOREIGN KEY(parent_id) REFERENCES _alembic_batch_temp (id) # old reference
)
To Avoid this situation you can create the batch migration manually:
Rename the old table to some temporary name:
ALTER TABLE my_table RENAME TO migration_temp_table;
Create new table with proper name and proper reference:
CREATE TABLE my_table (
id VARCHAR(24) NOT NULL,
parent_id VARCHAR(24),
PRIMARY KEY (id),
CONSTRAINT parent_constraint FOREIGN KEY(parent_id) REFERENCES my_table (id)
)
Copy the data:
INSERT INTO my_table (id) SELECT id FROM migration_temp_table;
Remove the old table:
DROP TABLE migration_temp_table;
I have created one table in oracle data base my table script is
CREATE TABLE wsc_widget_bundle (
id VARCHAR (50),
widgetBundle BLOB NULL,
devicesoftwareclass VARCHAR(30) NOT NULL,
widgetProfileId VARCHAR (50) NOT NULL,
bundleHash BLOB NULL,
widgetLocale VARCHAR (6) NOT NULL ,
status INT,
primary key(id),
unique(widgetProfileId, devicesoftwareclass,status),
foreign key(widgetProfileId) references wsc_widget_profile(id)
);
When i create ddl for that is looks like
create table "DEV1"."WSC_WIDGET_BUNDLE"(
"ID" VARCHAR2(50) not null,
"WIDGETBUNDLE" BLOB,
"DEVICESOFTWARECLASS" VARCHAR2(30) not null,
"WIDGETPROFILEID" VARCHAR2(50) not null,
"BUNDLEHASH" BLOB,
"WIDGETLOCALE" VARCHAR2(6) not null,
"STATUS" NUMBER,
constraint "SYS_C00323290" primary key ("ID")
);
alter table "DEV1"."WSC_WIDGET_BUNDLE"
add constraint "SYS_C00323292"
foreign key ("WIDGETPROFILEID")
references "MTP440_DEV1"."WSC_WIDGET_PROFILE"("ID");
create unique index "MTP440_DEV1"."SYS_C00323290" on "MTP440_DEV1"."WSC_WIDGET_BUNDLE"("ID");
create unique index "MTP440_DEV1"."SYS_C00323291" on "MTP440_DEV1"."WSC_WIDGET_BUNDLE"("WIDGETPROFILEID","DEVICESOFTWARECLASS","STATUS");
create index "MTP440_DEV1"."TEST" on "MTP440_DEV1"."WSC_WIDGET_BUNDLE"("DEVICESOFTWARECLASS","STATUS","WIDGETLOCALE","WIDGETPROFILEID");
Now i want to write alter script to alter unique key constrain of my table but as at creation of table I didn't mention the name of my unique key name it is given by system like SYS_C00323291
So how can I write alter script to drop that unique key whose name is not known to me and generation new one
You can find the name of the constraint by querying the user_constraints and user_cons_columns views.
Alter table x
drop constraint pk;
Alter table x
add constraint New_constraint_name PRIMARY KEY (colname);
I have two tables Cal and EEL
I want to use the primary key of cal that is Cal_id as the foreign key for EEl
Here's what I tried.
Create table ELL
(course_code varcahr2(10) Constraints pk_course_code Primary Key,
Course_Title varchar2(30),
cal2_idnumber not null,
Constraint fk_cal2 Foreign Key (cal_id) References cal_id(cal2_id)
)
but it shows error at line 6 Ora-00904 "Cal_ID" invalid character
can someone tell me how to do this
ALTER TABLE table_name
add CONSTRAINT constraint_name
FOREIGN KEY (column1, column2, ... column_n)
REFERENCES parent_table (column1, column2, ... column_n);
Not difficult, here below an example:
CREATE TABLE supplier
( supplier_id numeric(10) not null,
supplier_name varchar2(50) not null,
contact_name varchar2(50),
CONSTRAINT supplier_pk PRIMARY KEY (supplier_id)
);
CREATE TABLE products
( product_id numeric(10) not null,
supplier_id numeric(10) not null,
CONSTRAINT fk_supplier
FOREIGN KEY (supplier_id)
REFERENCES supplier(supplier_id)
);
References cal_id(cal2_id) -- call_id is not your table name.
Instead of above code you can use as below.
References parent_table_name(cal2_id)
Constraint fk_cal_id2 Foreign Key (cal2_id) References cal(cal_id)
----------- constraint name (col in EEL) parent table name(parent table column name)
I am having two tables tbluserlogindetail and tblRoles.
tbluserlogindetail is as follows
CREATE TABLE `tbluserlogindetail` (
`LoginID` varchar(45) NOT NULL,
`Name` varchar(45) DEFAULT NULL,
`Password` varchar(45) DEFAULT NULL,
PRIMARY KEY (`LoginID`),
UNIQUE KEY `LoginID_UNIQUE` (`LoginID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1$$
EDIT doratesting.tbluserlogindetail;
and my second table tblRoles is as follows
CREATE TABLE `tblroles` (
`RoleID` int(11) NOT NULL,
`LoginID` varchar(45) NOT NULL,
PRIMARY KEY (`RoleID`,`LoginID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1$$
I tried the the following to assign a primary key for the column LoginID in tblroles table but i don't know where i went wrong can any one help me.
I have gone through the documentation but unable to rectify the error so please help me
ALTER TABLE tblroles
ADD FOREIGN KEY (loginid)
REFERENCES tbluserlogindetail(loginid)
The referenced columns must be unique in the referenced table. Try one of these options:
The primary key on tbluserlogindetail is (ID, loginid) so you could use that as your foreign key instead of (loginid). This will require you to add a column tbluserlogindetail_ID to tblroles.
Try adding a unique index to the LoginID column of the tbluserlogindetail table. This is only possible if it is actually unique.
Also, why is your primary key on tbluserlogindetail defined as PRIMARY KEY (ID, LoginID)? The ID field is an auto-increment field and is already unique. So why do you also include the LoginID as part of the primary key? I think you need to go back to your table design and rethink which columns to choose as your primary keys.
this is just guess/ assumption ,i like to share here,
PRIMARY KEY (ID,LoginID)
in tbluserlogindetail are considered as surrogate key,
when we execute the child table,That is tblroles,
child table expected primary key in parent table,
but actually we created the surrogate key, due to this reason, i alter query failed,
ALTER TABLE tblroles ADD FOREIGN KEY (LoginID) REFERENCES tbluserlogindetail(LoginID)
This is my assumption, give feedback for my answer,
I did following changes to execute the Alter table command:
1.tblroles create with given Create query command, after created i manually deleted the
LoginID primary key in tblroles table,
Changed varchar to int in LoginID,
in tbluserlogindetail, deleted the ID AUTO_INCREMENT,Pk.
Check i updated ALTER query