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.
Related
I am creating a stored procedure, where I'm backing up certain values from my main database into another.
I have a loop that runs over the all tables and for certain tables I have different statements to create the backup tables, but they all look similar to this:
SET #backupQuery= NULL;
IF (tableName IN ('some_table', 'another_table')) THEN
SET #backupQuery= CONCAT(
'CREATE TABLE backup.', tableName, ' AS',
' SELECT * FROM mydb.', tableName
' WHERE row = "criteria");
ELSEIF (tableName IN ('table_with_other criteria')) THEN
SET #backupQuery= CONCAT(
...
IF (#backupQueryIS NOT NULL) THEN
PREPARE stmt from #backupQuery;
...
If the Select statement returns no rows, it still creates an empty table, this is something i don't want to have.
What will be the best way to avoid the empty tables?
My idea was to split into two parts: the SELECT part and the 'CREATE TABLE backup.' ,tableName, ' AS' part. Check if the SELECT statement returned any rows.
But I'm not sure how I can accomplish this.
Another approach would be to delete all empty tables in the end, but I really don't like this as the procedure is doing useless things.
I have hundreds of databases with some structurally identical (but over time changing) tables. Data of a certain table (from all DBS) should be copied into one central table ('ex_objects') in a central database ('db_central'; there are no pk conflicts). I've used a trigger in each DB for this purpose. But since the table structure is changing almost on a daily basis, it's a pain to update the fields in the ON DUPLICATE KEY part of the trigger's query. And someone could forget to modify the trigger after modifying the table structure. So I came across a possible solution to build that particular part of the query dynamically. This actually works on a script (PHP) basis, but I don't get the trigger done. I don't see what I am missing here.
BEGIN
DECLARE VAL_FIELDS TEXT;
SET VAL_FIELDS = (SELECT GROUP_CONCAT( CONCAT(COLUMN_NAME,"=values(", COLUMN_NAME,")") SEPARATOR ", ") FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'db_central' AND TABLE_NAME = 'ex_objects');
-- SELECT GROUP_CONCAT( CONCAT(COLUMN_NAME,"=values(", COLUMN_NAME,")") SEPARATOR ", ") INTO VAL_FIELDS FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'db_central' AND TABLE_NAME = 'ex_objects';
-- SELECT #VAL_FIELDS := GROUP_CONCAT( CONCAT(COLUMN_NAME,"=values(", COLUMN_NAME,")") SEPARATOR ", ") INTO VAL_FIELDS FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'db_central' AND TABLE_NAME = 'ex_objects';
IF NEW.online = 1 THEN
INSERT INTO db_central.ex_objects
SELECT * FROM ex_objects WHERE id = NEW.id AND client_id = NEW.client_id AND NEW.online = 1
ON DUPLICATE KEY UPDATE VAL_FIELDS;
END IF;
END
I get the error that there's something wrong at ; END IF; END. Well, that means for me, that either the VAL_FIELDS variable after KEY UPDATE isn't recognized at all or the parser expects at least one equation (something like VAL_FIELDS = whatever). But in this case, it wouldn't solve my underlying problem at all.
The SELECT GROUP_CONCAT( CONCAT(COLUMN_NAME,"=v ... FROM INFORMATION_SCHEMA.C ... Query works well and results in something similar to id=values(id), xfield=values(xfield), yfield=values(yfield) (but with a few hundred fields, since the table is actually pretty huge).
The full error: SQL Error (1064): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ';
END IF;
END' at line 10
You must build the SQL using CONCAT, etc, then prepare and execute it. There is no 'interpolation'.
Since it is a TRIGGER, that won't work.
However, since a TRIGGER applies to a particular table, you may as well simply spell out the query, not construct it. You have most of what it takes to manually get the query generated for you (SELECT ... I_S ...). Add some more columns for OLD.col to fill out the thing; viola, you have the query that you need.
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
I have a column 'seq' in every table of my database that I would like to delete easily.
I have to do this on occasion in MySQL and am hoping this can be automated.
There isn't a simple magical expression to just do this. You need to generate a list of SQL statements and then run them, somehow.
(Most database folks don't routinely drop columns from a database in production; it takes a lot of time during which the tables are inaccessible, and it's destructive. A fat-finger error could really mess you up.)
You might start by using the information_schema in MySQL to discover which of your tables have a seq column in them. This query will return that list of tables for the database you're currently using.
SELECT DISTINCT TABLE_NAME
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND COLUMN_NAME = 'seq'
You could then adapt that query to, for example, create a list of statements like this.
SELECT DISTINCT
CONCAT('UPDATE ',TABLE_NAME, ' SET seq = 0;') AS stmt
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND COLUMN_NAME = 'seq'
This will produce a result set like this:
UPDATE table_a SET seq = 0;
UPDATE table_b SET seq = 0;
UPDATE user SET seq = 0;
Then you could run these statements one by one. These statements will zero out your seq columns.
Edit
You can also do
CONCAT('ALTER TABLE ',TABLE_NAME, ' DROP COLUMN seq;') AS stmt
to get a drop column statement for each table.
But, you might consider creating views of your tables that don't contain the seq columns, and then exporting to PostgreSQL using those views. If your tables are significant in size, this will save you a lot of time.
I have a Microsoft stored procedure that queries two MySQL databases using OpenQuery. The two MySQL databases should be have the same schemas, so I can run the same query on both.
However, we will soon alter the MySQL schemas, and add a column to a table. But the two MySQL databases won't happen at the same time, and I don't know the exact date of the releases.
I therefore want to write the query so that if the new column exists, then I use it in my select. If not, then I use a default value.
Is this possible? (That is have a query that handles differences in the table schema?)
(Not to be confused with 'coelesce' where the field definitely exists, but is simply null.)
You can use the following SELECT statement:
SELECT *
FROM information_schema.COLUMNS
WHERE
TABLE_SCHEMA = 'database name' AND TABLE_NAME = 'your table name'
AND COLUMN_NAME = 'the column name you want to check for'
If the above returns a value, your column is there. If not, then run your alternative SELECT statement
Updated statement:
IF EXISTS (SELECT *
FROM OPENQUERY(servername, 'SELECT *
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = ''database name''
AND TABLE_NAME = ''your table name''
AND COLUMN_NAME = ''the column name you want to check for'' ))