I need a query that could drop primary key only if it exists.
ALTER TABLE tablename DROP PRIMARY KEY;
This will return error if it does not exists, but my requirement is to run a query in different databases.
In MariaDB 10.2.16 i was able to solve this problem with:
ALTER TABLE tablename DROP INDEX IF EXISTS `PRIMARY`;
This should work with any table since the primary keys in MySQL are always called PRIMARY as stated in MySQL doc:
The name of a PRIMARY KEY is always PRIMARY, which thus cannot be
used as the name for any other kind of index.
I would recommend using this:
SELECT CONCAT('ALTER TABLE ', TABLE_SCHEMA, '.',TABLE_NAME,
' DROP PRIMARY KEY; ANALYZE TABLE ', TABLE_SCHEMA, '.',TABLE_NAME, ';')
FROM information_schema.COLUMNS
WHERE CONCAT(TABLE_SCHEMA,TABLE_NAME,COLUMN_NAME) IN
(SELECT CONCAT(TABLE_SCHEMA,TABLE_NAME,COLUMN_NAME)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE INDEX_NAME = 'PRIMARY' -- *Required* to get only the primary keys from the statistics table.
-- *Optional*
AND TABLE_SCHEMA = 'clients_database');
Run this to generate your required SQL.
Copy your results, then run them as working queries.
ANALYZE TABLE is optional as well as the WHERE clause.
You can remove ANALYZE TABLE ', TABLE_SCHEMA, '.',TABLE_NAME, ';' if desired from the query below.
I exploit the information_schema when researching and utilizing standardization techniques.
Just about everything you would ever need or want to know about your tables and columns lives in some System table in either (if applicable)
Database / Table_schema:
information_schema
performance_schema
mysql
Note: From doc's
Internal schemas, such as "performance_schema", "information"schema", "sys", and "mysql", are hidden by default. Toggle the Show Metadata and Internal Schemas preference to list them in the object browser. Schemas beginning with a "." are also controlled by this setting.
NOTE: Here's something similar that has been created.
Hope this helps!
Cheers,
Jay
I think the easy option might be this:
first go to :
'YourDatabase'>tables>your table name>keys>copy the constraints like 'PK__TableName__0001'
then run this:
Query:alter Table 'TableName' drop constraint PK__TableName__0001
Related
Suddenly I've a strange problem with Mysql:
In the navigator I see the "company" table (even after refresh), but if I do SELECT * FROM company; says that the table does not exist.
With the command SHOW TABLES FROM smartex_develop; the table "company" is present, but if I use the command SELECT * FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'smartex_develop'; the table is missing. It's very strange also considering that there are a lot of table with a foreign key of that table.
Someone know how to resolve it?
[SELECT * FROM company] 1
[SHOW TABLES FROM smartex_develop] 2
[SELECT * FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'smartex_develop'] 3
We had a similar problem - a table suddenly went missing. In the logs we had:
Load table <name-of-missing-table> failed, the table has missing foreign key indexes. Turn off 'foreign_key_checks' and try again.
InnoDB: Foreign Key referenced table <name-of-missing-table> not found for foreign table <some-other-table>
This happened upon mysqld startup, so the root cause might have been much older than that. In our case, the root cause was charset conversions. We converted a few tables, and ended up with foreign keys where the column in one table and the column in the referenced table had different character sets.
How we solved:
Disable foreign key checks
Restart mysql -- the missing table will now reappear
Convert all the columns that reference each other to have the same character set. You can use this query: select table_name,column_name,CHARACTER_SET_NAME from INFORMATION_SCHEMA.COLUMNS where table_schema = 'myschema' and data_type='varchar';
Re-enable foreign key checks
Restart mysql -- all should be fine now
I have MySQL database about 5GB size and about 200 tables in it. All tables have prefix which I'd like to remove and I found some ideas for that.
The problem is that this database has referential integrity checking by using CONSTRAINT...FOREIGN KEY.
How to remove prefix from tables, including change in constraints, without manual modification or removing constraints?
Unfortunately you have to drop and recreate the foreign keys according to the mysql documentation on rename table:
Foreign keys that point to the renamed table are not automatically
updated. In such cases, you must drop and re-create the foreign keys
in order for them to function properly.
Use the tables in information_schema (mostly TABLES and COLUMNS) to construct the code you need. Perhaps 3 scripts would be wise:
SELECT CONCAT('ALTER TABLE ', table_name, ' DROP FOREIGN KEY ' ... ) FROM ...
SELECT CONCAT('RENAME TABLE ', ...
SELECT CONCAT('ALTER TABLE ', table_name, ' ADD FOREIGN KEY ' ... ) FROM ...
Then manually copy and paste the 3 scripts into the mysql commandline tool.
As for removing the prefix, look at the string functions MID, LOCATE, SUBSTRING_INDEX, etc., to see what would be useful.
I going to list all columns of a table except PRIMARY key in mysql.
Note : operation is automatically so I don't know the names of fields.
Can you help me for making this query?
This is something worth doing some research on, if you are going to be working with databases in any length.
All DBMS I have worked with thus far have a means of looking at the constraints, columns, and table information. The ones for MySQL that will help you do what you want are likely in the INFORMATION_SCHEMA:
TABLE_CONSTRAINTS The MySQL Reference for this is here.
SELECT table_name, constraint_name, constraint_type FROM INFORMATION_SCHEMA.table_constraints;
COLUMNS The MySQL reference for this is here.
SELECT column_name FROM INFORMATION_SCHEMA.columns;
KEY_COLUMN_USAGE
You should be able to do something like this to get what you want:
SELECT INFORMATION_SCHEMA.key_column_usage.column_name
FROM INFORMATION_SCHEMA.key_column_usage
JOIN INFORMATION_SCHEMA.table_constraints
ON INFORMATION_SCHEMA.key_column_usage.column_name = INFORMATION_SCHEMA.table_constraints.column_name
WHERE INFORMATION_SCHEMA.table_constraints.constraint_type <> 'PRIMARY KEY'
The should be essentially what you need. Views/tables like these can be your best friend when needing to get information about your schema.
I hope that this information helps.
Some SQL servers allow for a generic statement such as ORDER BY PRIMARY KEY. I don't believe this works for MySQL, is there any such workaround that would allow for automated selects across multiple tables or does it require a lookup query to determine the primary key?
The workaround I have been working on involves calling a SHOW COLUMNS FROM before running the query. Is there a more efficient way of doing this? Can MySQL determine the primary key of a table during the select process?
Update: There is no official way of doing this in MySQL or SQL in general as Gordon pointed out. SAP has custom functionality for it. There are workarounds, such as working with SHOW COLUMNS FROM table or the information_schema as John pointed out.
MySQL generally pulls data out by insertion order which would be by primary key, but that aside you technically can do the same thing if you pull out the primary key column name and put it in an order by
SELECT whatever FROM table
ORDER BY
( SELECT `COLUMN_NAME`
FROM `information_schema`.`COLUMNS`
WHERE (`TABLE_SCHEMA` = 'dbName')
AND (`TABLE_NAME` = 'tableName')
AND (`COLUMN_KEY` = 'PRI')
);
For composite keys you can use this
SELECT whatever FROM table
ORDER BY
( SELECT GROUP_CONCAT(`COLUMN_NAME` SEPARATOR ', ')
FROM `information_schema`.`COLUMNS`
WHERE (`TABLE_SCHEMA` = 'dbName')
AND (`TABLE_NAME` = 'tableName')
AND (`COLUMN_KEY` = 'PRI')
);
Permission for information schema access from the DOCS
Each MySQL user has the right to access these tables, but
can see only the rows in the tables that correspond to objects for
which the user has the proper access privileges. In some cases (for
example, the ROUTINE_DEFINITION column in the
INFORMATION_SCHEMA.ROUTINES table), users who have insufficient
privileges see NULL. These restrictions do not apply for InnoDB
tables; you can see them with only the PROCESS privilege.
The same privileges apply to selecting information from
INFORMATION_SCHEMA and viewing the same information through SHOW
statements. In either case, you must have some privilege on an object
to see information about it.
SETUP:
CREATE TABLE some_stuff (
firstID INT,
secondID INT,
username varchar(55),
PRIMARY KEY (firstID, secondID)
) ;
QUERY:
SELECT GROUP_CONCAT(`COLUMN_NAME` SEPARATOR ', ')
FROM `information_schema`.`COLUMNS`
WHERE (`TABLE_SCHEMA` = 'dbName')
AND (`TABLE_NAME` = 'some_stuff')
AND (`COLUMN_KEY` = 'PRI');
OUTPUT:
+--------------------------------------------+
| GROUP_CONCAT(`COLUMN_NAME` SEPARATOR ', ') |
+--------------------------------------------+
| firstID, secondID |
+--------------------------------------------+
SAP does, indeed do this (http://help.sap.com/saphelp_nw04s/helpdata/en/fc/eb3a53358411d1829f0000e829fbfe/content.htm). SQL Server is also based on Sybase, and I don't think Sybase supported this functionality. There are many limitations on the syntax.
On a query on one table with a primary key, no explicit order by, and no where conditions, MySQL will generally return the results in primary key order. You cannot depend on this functionality, but it might be good enough for your system.
The big issue would be the use of indexes for the where clause. If there are no indexes on the table, you don't have to worry about it. If there are, you could possibly emulate the behavior with a materialized view:
select t.*
from (select t.*
from table t
) t
where <where clause here>;
Another option is to force the database engine to use the primary key index. You can do this by using a force index hint. The issue is that you need to know the name of the index.
I am using MySQL v5.1.
I would like to create index on a table by executing the following SQL statement:
CREATE INDEX index_name
ON table_name (column_name)
But, I wan to firstly check if the index on that column has already been created or not, if not, create it (otherwise do not create). What is the SQL syntax for this?
Mysql doesn't have IF NOT EXISTS for CREATE INDEX. You can work it out by querying information_schema.statistics table. Take a look here, there is an example of stored procedure that does what you are looking for (search for "CREATE INDEX IF NOT EXISTS" on the page)
You want SHOW INDEX.
To get all the indexes on a table:
SHOW INDEX FROM table_name
MySQL allows you to add a WHERE clause to limit the results as well.
Lock the table while you're checking to see if the index exists (and if it doesn't exist, creating the index) so that another process doesn't create the index right after you've checked for it but before you've created it yourself.