View the constraints enforced on a table- SQL - mysql

Since I am not much of a DB guy, I have a query.I use Mysql.
I am given a table which has around 12 columns and that table has a PRIMARY key,UNIQUE & a FOREIGN key defined.
Is there a way to find on which columns the constraints are defined?
I came across one query:
SHOW INDEX FROM tablt_name;
But It does not give a clear idea, only the primary key column is displayed by the above query.
If there is any other way to get the info, pls help

You can try like thisL
USE information_schema;
SELECT table_name,
column_name,
constraint_name,
referenced_table_name,
referenced_column_name
FROM key_column_usage
WHERE table_schema = ""
AND table_name = ""
AND referenced_column_name IS NOT NULL;
or
DESCRIBE table_name

Related

Unknown table 'table_name' in information_schema

I want to show index from each table that has table_schema='foo' (database name).
mysql> show index from table_name from information_schema.tables where table_schema='foo';
ERROR 1109 (42S02): Unknown table 'table_name' in information_schema
From the error, I see that the query treats 'table_name' as a table in information_schema. How do I rewrite the query to treat 'table_name' as a column in information_schema.tables?
You're approaching this wrong, and you're making up syntax that doesn't exist.
I suggest the way you want to get the indexes is by reading the INFORMATION_SCHEMA.STATISTICS table, not the TABLES table.
The following query has the same columns as SHOW INDEXES:
SELECT table_name AS `Table`, Non_unique, index_name AS Key_name,
Seq_in_index, Column_name, Collation, Cardinality, Sub_part,
Packed, Nullable, Index_type, Comment, Index_comment
FROM INFORMATION_SCHEMA.STATISTICS
WHERE table_schema = 'foo';
You might think there should be an I_S table called "INDEXES" but in fact the system table for index objects is named "STATISTICS". Go figure.

MYSQL - set default as NULL to all columns, where default is not set

I have about 12 databases, each with 50 tables and most of them with 30+ columns; the db was running in strict mode as OFF, but now we had to migrate the db to cleardb service which by default has strict mode as ON.
all the tables that had "Not Null" constraint, the inserts have stopped working, just because the default values are not being passed; while in case of strict mode as OFF if the value are not provided, the MYSQL will presume the default value of the column datatype.
Is there a script I can use to get the metadata about all the columns of all tables and generate a script to alter all the tables with such columns to change the default to "Null"
You should consider using the information_schema tables to generate DDL statements to alter the tables. This kind of query will get you the list of offending columns.
SELECT CONCAT_WS('.',TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME) col
FROM information_schema.COLUMNS
WHERE IS_NULLABLE = 0
AND LENGTH(COLUMN_DEFAULT) = 0
AND TABLE_SCHEMA IN ('db1', 'db2', 'db3')
You can do similar things to generate ALTER statements to change the tables. But beware, MySQL likes to rewrite tables when you alter certain things. It might take time.
DO NOT attempt to UPDATE the information_schema directly!
You could try changing the strict_mode setting when you connect to the SaaS service, so your software will work compatibly.
This is a large project and is probably important business for cleardb. Why not ask them for help in changing the strict_mode setting?
This is what I came up with on the base of #Ollie-jones script
https://gist.github.com/brijrajsingh/efd3c273440dfebcb99a62119af2ecd5
SELECT CONCAT_WS('.',TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME) col,CONCAT('alter table ',TABLE_NAME,' MODIFY COLUMN ', COLUMN_NAME,' ',DATA_TYPE,'(',CHARACTER_MAXIMUM_LENGTH,') NULL DEFAULT NULL') as script_col
FROM information_schema.COLUMNS
WHERE is_nullable=0
and length(COLUMN_DEFAULT) is NULL and
CHARACTER_MAXIMUM_LENGTH is not NULL and
table_schema = 'immh'
Union
SELECT CONCAT_WS('.',TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME) col,CONCAT('alter table ',TABLE_NAME,' MODIFY COLUMN ', COLUMN_NAME,' ',DATA_TYPE,' NULL DEFAULT NULL') as script_col
FROM information_schema.COLUMNS
WHERE is_nullable=0
and length(COLUMN_DEFAULT) is NULL and
CHARACTER_MAXIMUM_LENGTH is NULL and
table_schema = 'immh'

Delete MySQL column index without knowing its name

I have an application which uses Hibernate to support Oracle and MySQL databases. After an update I have to manually delete some columns with indexes/constraints on it. These indexes have Hibernate generated random names.
In Oracle I can do this:
ALTER TABLE table_name DROP (column_name) CASCADE CONSTRAINTS;
Unfortunately this isn't possible for MySQL. Is there a possibility to do something like this
DROP INDEX (SELECT Key_name FROM (SHOW INDEX FROM table_name WHERE Column_name = 'column_name')) ON table_name;
before I drop the column?
EDIT: This should work without user interaction in a SQL script.
You can select indexes for a table form information_schema:
SELECT DISTINCT INDEX_NAME, TABLE_NAME, TABLE_SCHEMA FROM information_schema.STATISTICS;
There is no need to manually delete the indexes, MySQL 5.7 Reference Manual says:
If columns are dropped from a table, the columns are also removed from
any index of which they are a part. If all columns that make up an
index are dropped, the index is dropped as well. If you use CHANGE or
MODIFY to shorten a column for which an index exists on the column,
and the resulting column length is less than the index length, MySQL
shortens the index automatically.
To get all indexes for a particular database (replace <Database_Name> with your database name), use:
SELECT DISTINCT INDEX_NAME
FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA LIKE '<Database_Name>';
To get all indexes for a table (replace <Table_Name> with your table name) of a particular database, use:
SELECT DISTINCT INDEX_NAME
FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA LIKE '<Database_Name>' AND
TABLE_NAME LIKE '<Table_Name>';
To get all indexes of a specific column (replace <Column_Name> with your column name) of a table in a particular database, use:
SELECT DISTINCT INDEX_NAME
FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA LIKE '<Database_Name>' AND
TABLE_NAME LIKE '<Table_Name>' AND
COLUMN_NAME LIKE '<Column_Name>';
In addition to that, you may also use any Wildcard character in the LIKE operator to get specific records, like:
SELECT DISTINCT INDEX_NAME
FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA LIKE '<Database_Name>' AND
TABLE_NAME LIKE 'tbl_prefix_%';

Query to find foreign keys

I have a database where I need to drop some foreign keys, but I don't know beforehand whether the foreign keys still exist.
I've found some stored procedures (http://forums.mysql.com/read.php?97,218825,247526) that does the trick, but I don't want to create a stored procedure for this.
I've tried to use the query inside the stored procedure, but I get an error using "IF EXISTS (SELECT NULL FROM etc.. etc...
Can I only use IF EXISTS in stored procedures?
right now, the only thing I can run is
SELECT * FROM information_schema.TABLE_CONSTRAINTS
WHERE information_schema.TABLE_CONSTRAINTS.CONSTRAINT_TYPE = 'FOREIGN KEY'
AND information_schema.TABLE_CONSTRAINTS.TABLE_SCHEMA = 'myschema'
AND information_schema.TABLE_CONSTRAINTS.TABLE_NAME = 'mytable';
and I've tried this too
IF EXISTS (SELECT NULL FROM information_schema.TABLE_CONSTRAINTS WHERE CONSTRAINT_SCHEMA = DATABASE() AND CONSTRAINT_NAME = parm_key_name) THEN
(...) do something (...)
END IF;
but I get a 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 'IF' at line 1
I've looked for examples in forums with simple queries and I can't make sense of why this isn't working.
NOTE: Edit to correct broken link
You need to connect to the Information scheme and you can find all the information about the primary key and foreign keys in this table
SELECT * FROM information_schema.TABLE_CONSTRAINTS T;
you need to be a ROOT user to access the information_schema.
USING this table you can find the table, db and whether it has foreign key.
Hope this helps if you dont wanna use IF EXIST and Stored Procedure. But I am Sure you can use IF EXIST can be used for non stored procedure queries....
Why don't You use the table "INFORMATION_SCHEMA" to this?
SELECT *
FROM information_schema.TABLE_CONSTRAINTS
WHERE CONSTRAINT_TYPE = 'FOREIGN KEY'
You need to connect to the Information scheme and you can find all the information about the primary key and foreign keys in this table
select
concat(table_name, '.', column_name) as 'foreign key',
concat(referenced_table_name, '.', referenced_column_name) as 'references'
from
information_schema.key_column_usage
where
referenced_table_name is not null;
HELP: see this link list-foreign-keys-in-mysql

Mysql show create constraint?

Is there a easy way to query a table for its constraints(foreignkeys specificaly)
like show create table, but for the constraints only?
thanks,
pvgoddijn
To show only the foreign key constraints you can check the constraint_type in information_schema.table_constraints and get the affected columns in information_schema.key_column_usage via a join
SELECT b.table_name, b.column_name, b.constraint_name,
b.referenced_table_name, b.referenced_column_name
FROM information_schema.table_constraints a
JOIN information_schema.key_column_usage b
ON a.table_schema = b.table_schema AND a.constraint_name = b.constraint_name
WHERE a.table_schema=database() AND a.constraint_type='FOREIGN KEY'
ORDER BY b.table_name, b.constraint_name;
select * from
information_schema.KEY_COLUMN_USAGE
where table_schema = <db_name>
and table_name = <table_name>;
SHOW TABLE STATUS FROM db_name LIKE 'tbl_name';
The foreign key constraints are listed in the Comment column of the output.
MySQL 5.1 Manual
SHOW TABLE STATUS FROM db_name LIKE 'tbl_name';