create table if not exists, insert columns if missing, best way - mysql

I need to create a table if it doesnt exist, and add missing columns in the proper order if the table already exists.
I know how to do it with lots of queries, and if statements and so on, but what I am asking here is what the best solution would be.. Maybe there is a special query to do this, or a smart way.
I would do it this way:
create table if not exists (all columns as they should be)
compare all the columns (if some are missing they will be added, else not)
Is this the best way or are there better ways to do it?
ADDITIONAL INFO
the colums need to be added at the right position. I have a list of strings representing all the columns in the proper order. using vb.net I am iterating through these strings.

Check out this for instance. It's basically about querying the data dictionary and adding columns only if they do not exist:
IF NOT EXISTS(SELECT NULL
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'tablename'
AND table_schema = 'db_name'
AND column_name = 'columnname') THEN
ALTER TABLE `TableName` ADD `ColumnName` int(1) NOT NULL default '0';
END IF;
Putting it in a procedure makes it quite handy.
p.s. note about column positions: from the docs
To add a column at a specific position within a table row, use FIRST
or AFTER col_name. The default is to add the column last. You can also
use FIRST and AFTER in CHANGE or MODIFY operations to reorder columns
within a table.

You can use following codes for that:
if not exists(select * from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'table_name' and COLUMN_NAME = 'column_name')
BEGIN
ALTER TABLE table_name ADD
ToUser uniqueidentifier NULL
END

Related

Use auto incremented ID in another column

I have two columns in my DB table, where the first one is auto incremented ID. In the second one I would like to have that ID mirrored. (I know it sound like design error, but I really need it)
Is it possible to configure it that way?
If you're using MySql 5.7.6 or later you can define the second id as a virtual column like this:
CREATE TABLE my_table (
id INT UNSIGNED AUTO_INCREMENT,
id_mirrored INT UNSIGNED AS (id)
);
This way the id_mirrored column isn't really stored in your database but instead it's evaluated when the row is read.
If you're using an earlier version of MySql creating a view is probably your best option. Views are basically virtual tables.
CREATE VIEW my_view AS
SELECT
t.id AS id,
t.id AS id_mirrored
FROM my_table t
Third option is to define the id_mirrored as a real column and add a trigger to give it it's value. The way to do this has already been described in other answers.
use TRIGGER
DELIMITER |: # switch delimiter to prevent execution of ;
CREATE TRIGGER `copy_id2c_name` BEFORE INSERT ON tb_name
FOR EACH ROW BEGIN
SELECT AUTO_INCREMENT INTO #AI FROM information_schema.tables WHERE table_schema = 'db_name' and table_name = 'tb_name';
set NEW.c_name = #AI;
END;
|: # execute code
DELIMITER ; // switch back original delimiter
You could use smth like LAST_INSERT_ID() in case you are using stored procedure.

Hidden character in SQL column

I've copied and pasted an SQL statement which simply adds a column into the table:
ALTER TABLE `users` ADD COLUMN `favourites​` TEXT;
However, where I have copied and pasted, the favourites name has some how managed to pick up a hidden character.
I have left the hidden character in the example above for you to see/or not see as it may be!
It's favourites?, with what appears to be a question mark.
THE PROBLEM: I need to delete this column and re-add it manually so that the hidden character is not present. The problem is that any SQL statement I do, it doesn't recognise the the column name favourites because of the hidden character and I don't know how to target it.
Has anyone got any idea how to get around this?
Do the same use show
SHOW COLUMNS FROM your_table;
for obtain the column name and then copy the column you need in your delete command
alter table your_table drop column your_column_copied
and the add the column with the right name
alter table your_table add column your_column
otherwise, if is impossible get the column_name, you can create a temp table without the wrong column with create/select command
create table (col1, col2, col3)
select col1,col2, col3
from you_table
then drop the original table and rename the temporary table and last add your column with right name
You could use dynamic query:
DECLARE #sql nvarchar(800)
SELECT #sql = 'ALTER TABLE users DROP COLUMN ' + COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'users' and COLUMN_NAME LIKE '%favour%'
EXEC sp_executesql #sql
You can obtain the column name by querying INFORMATION_SCHEMA and prepare statement with the obtained column name. Something like this:
DECLARE #StrangeColumnName NVARCHAR(16) := ''
SELECT #StrangeColumnName := COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'users' AND COLUMN_NAME LIKE 'favourites%'
DECLARE #SqlText NVARCHAR(32) := 'ALTER TABLE status DROP COLUMN ?'
EXECUTE #SqlText USING #StrangeColumnName
Maybe open the information schema of the table and copy the column name from there? i don't know which Database are you using. Please update for more information.
If you have access to phpMyAdmin or, if you can create a small script to run this script:
SELECT COLUMN_NAME, FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'your_tbl_name'
OR
SHOW COLUMNS
FROM 'your_tbl_name
and copy the column name from the page.
next, you can drop that column using
alter table your_tbl_name drop column column_name;
and you already know how to add a column in mysql so, i guess that should solve your problem.
I hope you do know that you can not comment if your reputation is below 50 and if you didn't provide enough information, those who might actually have an answer for you, but have below 50 rep, will have to post it in answers. or would you like to eliminate those who are 50 rep as candidates for helping you?
In order to delete a column you can use:
alter table <tblname> drop column <colname>
and then after deleting the column you can add the column by writing below code:
ALTER TABLE users ADD COLUMN favourites​ TEXT;
Some possibilities:
Using phpmyadmin
Using a tool to talk directly to the database like navicat etc

Replace text through the entire database without assigning table or column

I've been using the following query to replace certain data:
UPDATE wx3_t1 SET umo = REPLACE(umo, 'stringbefore', 'string after');
wx3_t1 = Table
umo = Column
I am looking for a way to update across the entire database, without needing to put the table or the column into the query.
Something as simple as just REPLACE('stringbefore', 'string after')
I realize that doing it this way is really aggressive but that's fine.
You can create a simple script that query information_schema.COLUMNS to get list of all your columns by table:
select TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME from information_schema.COLUMNS;
Then you have to iterate on the result to play your UPDATE query.

How to insert columns at a specific position in existing table?

I created a table with 85 columns but I missed one column. The missed column should be the 57th one. I don't want to drop that table and create it again. I'm looking to edit that table and add a column in the 57th index.
I tried the following query but it added a column at the end of the table.
ALTER table table_name
Add column column_name57 integer
How can I insert columns into a specific position?
ALTER TABLE by default adds new columns at the end of the table. Use the AFTER directive to place it in a certain position within the table:
ALTER table table_name
Add column column_name57 integer AFTER column_name56
From mysql doc
To add a column at a specific position within a table row, use FIRST or AFTERcol_name. The default is to add the column last. You can also use FIRST and AFTER in CHANGE or MODIFY operations to reorder columns within a table.
http://dev.mysql.com/doc/refman/5.1/en/alter-table.html
I googled for this for PostgreSQL but it seems to be impossible.
Try this
ALTER TABLE tablename ADD column_name57 INT AFTER column_name56
See here
if you are saying ADD COLUMN column_name then it will throw error
u have to try
ALTER TABLE temp_name ADD My_Coumn INT(1) NOT NULL DEFAULT 1
remember if table already has few record and u have to create new column then either u have to make it nullable or u have to define the default value as I did in my query
ALTER TABLE table_name ADD COLUMN column_name integer
ALTER TABLE table_name ADD COLUMN column_name57 INTEGER AFTER column_name56
SET
#column_name =(
SELECT COLUMN_NAME
FROM
information_schema.columns
WHERE
table_schema = 'database_name' AND TABLE_NAME = 'table_name' AND ordinal_position = 56
);
SET
#query = CONCAT(
'ALTER TABLE `table_name` ADD `new_column_name` int(5) AFTER ',
#column_name
);
PREPARE
stmt
FROM
#query;
EXECUTE
stmt;
DEALLOCATE
stmt;
As workaround one could consider the use of column renaming.
I.e. add the new column at the end, and then until the new column is at the right position, add a temporary column for each column whose position is after the new column, copy the value from the old column to the temporary one, drop the old column and finally rename the temporary column.
see also: https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1770086700346491686
I tried to alter the table like so:
table_name add column column_name after column column_name;
The first column_name is the new column name, the second column_name is the existing column where you plan to insert into after.

Set all the columns of a mysql table to a particular value

hIs there any way to update all the columns of a mysql table for a particular record in one go to a particular value.
For e.g. I have a table that has around 70 columns , and they are by default set to 0 at the time of creating the table,when I add a new record via PHPmyadmin by just filling in one or two values and submitting it all the other fields are set to 0 , but I want to set all the fields to 1
many times ,so I need to set all the columns to 1 individually via PHPmyadmin
To speed-en up the process and
I tried
UPDATE tablename SET * = '1' WHERE id = '2' , but it does not work.
If anyone can provide a solution on similar lines , it would be great.
EDIT:
Is there a way without specifying all the 70 columns in the SQL statement? that what I am looking for. I do know how to update normally specifying columns in the SQL statement. Thank you.
If you are looking for a way to update all 70 columns to a single value with a short, simple statement, then I recommend that you write a stored procedure to do the update. That way you only need to write out the full update syntax once, and can re-use it over and over by calling the stored procedure.
CREATE PROCEDURE update_all_columns (p_new_value SMALLINT, p_id INT) ...
CALL update_all_columns(1,2);
Another trick is to use the information_schema.columns table to generate the update statement, making it less tedious to code the stored procedure.
Something like this:
SELECT concat('UPDATE ',
table_name,
' SET ',
group_concat(column_name separator ' = p_new_value, '),
' = p_new_value',
' WHERE id = p_id;') as sql_stmt
FROM information_schema.columns
WHERE table_schema = 'your_schema'
AND table_name = 'tablename'
AND column_name != 'id'
You have to name each column in an update statement.