Mysql:Trim all fields in database - mysql

UPDATE mytable SET mycolumn= LTRIM(RTRIM(mycolumn));
works fine on trimming columns removing trailer spaces, but how can i adjust it to trim all columns without having to write each column name in table ?? cause i kind have a huge database.

Some years late, but might help others:
This code trims all fields of a the table your_table.
Could be expanded to work on the whole database in the same way....
SET SESSION group_concat_max_len = 1000000;
SELECT concat('update your_table set ',
group_concat(concat('`',COLUMN_NAME, '` = trim(`',COLUMN_NAME,'`)')),';')
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'your_table'
INTO #trimcmd;
PREPARE s1 from #trimcmd;
EXECUTE s1;
DEALLOCATE PREPARE s1;

you expand the query for each column:
UPDATE mytable
SET mycolumn = LTRIM(RTRIM(mycolumn)),
mycolumn2 = LTRIM(RTRIM(mycolumn2)),
...;

Since the question asks for the whole database, here is the script that generates the required SQL. I skip the auto execute, execute it as you like.
-- Set your database name here
SET #my_database:='YOUR_DB_NAME';
SET SESSION group_concat_max_len = 1000000;
SELECT
CONCAT('UPDATE `', #my_database, '`.`', TABLE_NAME,
'` SET ', GROUP_CONCAT(
CONCAT('`', COLUMN_NAME, '` = TRIM(`', COLUMN_NAME, '`)')
ORDER BY ORDINAL_POSITION ASC),
';') AS `query`
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_SCHEMA = #my_database
GROUP BY TABLE_NAME
ORDER BY TABLE_NAME ASC;
#ZweiStein Thanks.

UPDATE mytable SET
mycolumn = LTRIM(RTRIM(mycolumn)),
mycolumn2 = LTRIM(RTRIM(mycolumn2))
and so on, and so forth.

If there are not too many columns, you could just
directly
UPDATE each by your_column_name, via the TRIM() function:
UPDATE mytable SET
mycolumn1 = TRIM(mycolumn1),
mycolumn2 = TRIM(mycolumn2),
mycolumn3 = TRIM(mycolumn3),
mycolumn4 = TRIM(mycolumn4)
Otherwise, ZweiStein's answer above for a single table,
or Izhar Aazmi's answer for an entire database seem the way to go.
Hiram's answer to another SO Post includes a check to only TRIM VARCHAR fields: excellent feature!
Or, if using T-SQL, or others which do not support TRIM, use the LTRIM(RTRIM(...)) trick,
suggested by Jim Rubenstein and Denis de Bernardy above.

I was actually looking for something similar for a legacy table that's constantly updated by an outside source when I came across this question. I realize the OP was looking for a purely SQL(MySQL) answer, but in case you use Rails, you might find this tidbit that I came up with helpful:
MyModel.update_all(MyModel.columns.map(&:name).map{|x| "#{x} = TRIM(#{x})"}.join(', '))
You can also wrap it into a class method in your model
class MyModel < ActiveRecord::Base
def self.trim_all
update_all(columns.map(&:name).map{|x| "#{x} = TRIM(#{x})"}.join(', '))
end
end
Then call it like this
MyModel.trim_all

You can use PHP for it ( in order to avoid sql errors, better print queries then execute them later ) :
$dbHost = 'localhost';
$dbUsername = 'root';
$dbPassword = '';
$dbName = 'database';
$db = new mysqli($dbHost, $dbUsername, $dbPassword, $dbName);
$db->set_charset("utf8");
$queries = '';
$query="SELECT * from table";
$result = $db->query($query);
$headers = $result->fetch_fields();
foreach($headers as $header) {
$col = $header->name;
$queries .= "UPDATE table SET `".$col."` = TRIM(`".$col."`) </br>";
}
echo $queries;
?>

Related

How to call MySQL function for every column that is present in table?

I need to call a mySQL function for all columns in a table.
I know how to do it for a particular column
Like this:
UPDATE `table_name` set `column_name` = function_name(`column_name`)
But i have no clue how to do it for all columns at once.
Thanks in advance.
Little clarification: I dont want to manually mention all columns, as i probably could have 200 columns table.
But i have no clue how to do it for all columns at once.
You just can't - there is no such shortcut in the update syntax.
You can do this with a single update statement, but you need to enumerate each and every column, like:
update table_name set
column_name1 = function_name(column_name1),
column_name2 = function_name(column_name2),
column_name3 = function_name(column_name3)
An alternative would be to use dynamic SQL to programatically generate the proper query string from catalog table information_schema.columns, and then execute it. This seems uterly complicated for what looks like a one-shot task... But here is sample code for that:
-- input variables
set #table_schema = 'myschema';
set #table_name = 'mytable';
set #function_name = 'myfunction';
-- in case "GROUP_CONCAT()" returns more than 1024 characters
set session group_concat_max_len = 100000;
-- build the "set" clause of the query string
select
#sql := group_concat(
'`', column_name, '` = ', #table_schema, '.', #function_name, '(`', column_name, '`)'
separator ', '
)
from information_schema.columns
where table_schema = #table_schema and table_name = #table_name;
-- entire query string
set #sql := concat('update ', #table_schema, '.', #table_name, ' set ', #sql);
-- debug
select #sql mysql;
-- execute for real
prepare stmt from #sql;
execute stmt;
deallocate prepare stmt;

How to loop through all the tables on a database to update columns

I'm trying to update a column (in this case, a date) that is present on most of the tables on my database. Sadly, my database has more than 100 tables already created and full of information. Is there any way to loop through them and just use:
UPDATE SET date = '2016-04-20' WHERE name = 'Example'
on the loop?
One painless option would be to create a query which generates the UPDATE statements you want to run on all the tables:
SELECT CONCAT('UPDATE ', a.table_name, ' SET date = "2016-04-20" WHERE name = "Example";')
FROM information_schema.tables a
WHERE a.table_schema = 'YourDBNameHere'
You can copy the output from this query, paste it in the query editor, and run it.
Update:
As #PaulSpiegel pointed out, the above solution might be inconvenient if one be using an editor such as HeidiSQL, because it would require manually copying each record in the result set. Employing a trick using GROUP_CONCAT() would give a single string containing every desired UPDATE query in it:
SELECT GROUP_CONCAT(t.query SEPARATOR '; ')
FROM
(
SELECT CONCAT('UPDATE ', a.table_name,
' SET date = "2016-04-20" WHERE name = "Example";') AS query,
'1' AS id
FROM information_schema.tables a
WHERE a.table_schema = 'YourDBNameHere'
) t
GROUP BY t.id
You can use SHOW TABLES command to list all tables in database. Next you can check if column presented in table with SHOW COLUMNS command. It can be used this way:
SHOW COLUMNS FROM `table_name` LIKE `column_name`
If this query returns result, then column exists and you can perform UPDATE query on it.
Update
You can check this procedure on sqlfiddle.
CREATE PROCEDURE UpdateTables (IN WhereColumn VARCHAR(10),
IN WhereValue VARCHAR(10),
IN UpdateColumn VARCHAR(10),
IN UpdateValue VARCHAR(10))
BEGIN
DECLARE Finished BOOL DEFAULT FALSE;
DECLARE TableName VARCHAR(10);
DECLARE TablesCursor CURSOR FOR
SELECT c1.TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS c1
JOIN INFORMATION_SCHEMA.COLUMNS c2 ON (c1.TABLE_SCHEMA = c2.TABLE_SCHEMA AND c1.TABLE_NAME = c2.TABLE_NAME)
WHERE c1.TABLE_SCHEMA = DATABASE()
AND c1.COLUMN_NAME = WhereColumn
AND c2.COLUMN_NAME = UpdateColumn;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET Finished = TRUE;
OPEN TablesCursor;
MainLoop: LOOP
FETCH TablesCursor INTO TableName;
IF Finished THEN
LEAVE MainLoop;
END IF;
SET #queryText = CONCAT('UPDATE ', TableName, ' SET ', UpdateColumn, '=', QUOTE(UpdateValue), ' WHERE ', WhereColumn, '=', QUOTE(WhereValue));
PREPARE updateQuery FROM #queryText;
EXECUTE updateQuery;
DEALLOCATE PREPARE updateQuery;
END LOOP;
CLOSE TablesCursor;
END
This is just an example how to iterate through all tables in database and perform some action with them. Procedure can be changed according to your needs.
Assuming you are using MySQL, You can use Stored Procedure.
This post is a very helpful.
Mysql-loop-through-tables

MySQL Select columns where the column name contains a substring

I have a table with a lot of fields about a person and then several recommendations of other people.
They are named:
"recommendation_1_name" "recommendation_1_company" 'recommendation_1_contact"
"recommendation_2_name" "recommendation_2_company" "recommendation_2_contact"
and so on.
I am trying to come up with a statement that allows me to only get the recommendations.
I imported an excel file into the table so it's just one large table.
This is what I have and it is returning an Empty set.
select * from questionnaire where 'COLUMN_NAME' like '%recommendation%';
I've been playing around with it making a table with only the recommendation fields and it still doesn't return anything.
Mysql: select recommendation_1_name, recommendation_2_name etc... from (table) where (USER) = (USERID) or however you can uniquely identify that user.
This Query generates you dynamic a SELECT query with all fields like 'recommendation%'. You only must setup the Databasename, and the Tablename. You can directly query the result of my query or add the WHERE clause.
SELECT
CONCAT( 'SELECT ',
GROUP_CONCAT(COLUMN_NAME SEPARATOR ',\n')
)
FROM information_schema.columns
WHERE TABLE_SCHEMA = 'DBNAME'
AND TABLE_NAME = 'TABLENAME'
AND COLUMN_NAME LIKE 'recommendation%';
You really need to normalize your schema.
But just as an experiment and example for some other cases (maybe somebody really need it). Here is solution to get this case resolved using stored procedure:
CREATE PROCEDURE `get_recommendations`()
BEGIN
DECLARE Q VARCHAR(100);
DECLARE C_NAME VARCHAR(100);
DECLARE cur CURSOR FOR SELECT GROUP_CONCAT(column_name) as `columns`
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'test'
AND TABLE_NAME ='questionnaire'
AND COLUMN_NAME LIKE '%recommendation%'
;
SET Q = 'SELECT ';
OPEN cur;
FETCH cur INTO C_NAME;
SET Q = CONCAT(Q,C_NAME,' ');
CLOSE cur;
SET #Q = CONCAT(Q,'FROM questionnaire;');
PREPARE stmt FROM #Q;
EXECUTE stmt ;
END
Don't forget to replace TABLE_SCHEMA = 'test' with your real database name.

Dynamic MySQL Update Statement

I'm trying to write a prodecure that updates a value in a given column-name where the users id equals given user ID.
_strong_1 is a variable that contains the column name, i.e: 'category_1', for example.
SELECT COLUMN_NAME FROM information_schema.`COLUMNS` C
WHERE table_name = 'subscribers_preferences' AND COLUMN_NAME LIKE _strong_1 INTO #columns;
SET #table = 'subscribers_preferences';
SET #s = CONCAT('UPDATE ',#table,' SET ', #columns = 1);
PREPARE stmt FROM #s;
EXECUTE stmt;
There's an error within the 'SET #s =' statement. I can get it to work with a simple SELECT statement, but UPDATE is being tricky.
Thanks in advance.
You need to put = 1 in quotes.
SET #s = CONCAT('UPDATE ',#table,' SET ', #columns, ' = 1');
Otherwise, you're comparing #columns with 1, and concatenating either 1 or 0 (probably always 0, since I doubt you have a column named 1) to the SQL, which is creating invalid SQL.
Note that the above code will only update one column. If #columns is supposed to hold 3 columns, you need to use GROUP_CONCAT in your query that sets it.
SELECT GROUP_CONCAT(CONCAT(column_name, ' = 1')) AS #columns
FROM information_schema.columns
WHERE table_name = 'subscribers_preferences' and column_name LIKE _strong_1;
SET #table = 'subscribers_preferences';
SET #s = CONCAT('UPDATE ',#table,' SET ', #columns);
I suspect you also need to add a WHERE clause to this SQL so it just updates the row for the given ID. As currently written, it will update all rows.
The fact that you need to write the query like this suggests improper normallization of your data. Instead of having each preference option in a different column, they should be different rows of the table, with the key being something like (user_id, setting_name).

Using mySQL variables

Is it possible in a sequence of SQL statements to get the value of a field and use that to name a table in another statement? I'm not sure if that's clear, so here's an psudo-example of what I'm trying to do:
// dataType is equal to "ratings"
#var = select dataType from theTable where anID = 5;
// needs to run as "from ratings-table"
select field1,field2 from #var-table where anID = 5;
I've been reading http://dev.mysql.com/doc/refman/5.0/en/user-variables.html but either I don't properly understand this, or its not the solution I'm looking for.
Yes, you can do this using prepared statements:
SET #TableName := 'ratings';
SET #CreateQuery := CONCAT('SELECT `field1`, `field2` FROM `', #TableName, '-table` WHERE `anID` = 5');
PREPARE statementCreate FROM #CreateQuery;
EXECUTE statementCreate;