Convert MySQL Variable Query to PostgreSQL - mysql

I have migrated MYSQL database to PostgreSQL and I am now converting my queries to match. I have this MySQL query in the Python file:
SET #Drop_Stm = CONCAT('DROP TABLE ', (SELECT GROUP_CONCAT(TABLE_NAME) AS All_Tables
FROM information_schema.tables
WHERE TABLE_NAME LIKE 'temp_%' AND TABLE_SCHEMA = '{client_name}'))
 
I would like to make it works in Postgres, I tried the following but returns error:
WITH Drop_Stm AS (CONCAT('DROP TABLE ', (SELECT STRING_AGG(TABLE_NAME, ',') AS All_Tables
FROM information_schema.tables
WHERE TABLE_NAME LIKE 'temp_%' AND TABLE_SCHEMA = '{client_name}')))
LINE 1: WITH Drop_Stm AS (CONCAT('DROP TABLE ', (SELECT STRING_AGG(T...
^
I also tried DECLARE, SET, and DO $$ .. END $$ with no luck

The query itself should be changed to this:
select concat('drop table ', string_agg(format('%I.%I', table_schema, table_name), ','), ' cascade;')
FROM information_schema.tables
WHERE TABLE_NAME LIKE 'temp_%'
AND TABLE_SCHEMA = '{client_name}'
Note that I used the format() function to properly deal with identifiers needing quoting. I also generated a fully qualified table name (including the schema) so that you don't accidentally drop a table in the current schema, rather than {client_name}.
If you want to run the generated script, I see two options. One is to put this into a PL/pgSQL block and use execute:
do
$$
declare
l_stmt text;
begin
select concat('drop table ', string_agg(format('%I.%I', table_schema, table_name), ','), ' cascade;')
into l_stmt
FROM information_schema.tables
WHERE TABLE_NAME LIKE 'temp_%'
AND TABLE_SCHEMA = '{client_name}';
execute l_stmt;
end;
$$
;
I don't know Python, so I am not entirely sure if {client_name} gets replaced correctly with that approach.
Another option is to run the SELECT query in Python, and store the result into a Python variable then run that SQL through Python.

Related

Truncate in multiple tables

I'm trying to create a way for me to apply truncate across multiple tables at the same time.
I tried the following code:
SELECT CONCAT('TRUNCATE TABLE ',table_schema,'.',TABLE_NAME, ';')
FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema in ('mytable1','mytable2','mytable3');
More unsuccessfully, it is not truncating the tables.
Does anyone know of any way to do this?
DECLARE #CODE NVARCHAR(MAX) = '', #XML XML
SET #XML = STUFF((
SELECT ' ' + data.CODE_DELETE
FROM (
SELECT CONCAT ('TRUNCATE TABLE ', table_schema, '.', TABLE_NAME, '') AS CODE_DELETE
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME IN ('CITY', 'WORKERS')
) [data]
FOR XML PATH('')
), 1, 1, '')
SET #CODE = CAST(#XML AS VARCHAR(MAX))
SELECT #CODE
EXECUTE sp_executesql #CODE;
the variable #XML is to be able to convert the rows into a single value, then we must convert the sql code to varchar in order to execute it with
EXECUTE sp_executesql #CODE;
you can see the code that will be executed if you do this:
SELECT #CODE
city ​​and workers are tables that I have in my database, if you look I change table_schema by TABLE_NAME in the WHERE clause.
Please use transaction to do it if you want to keep it atomic.
START TRANSACTION;
// Your truncate statements;
COMMIT;

Replace space with underscore in all table names in database

I'm trying to replace all space (' ') with a underscore in all the table names in a database using PhpMyAdmin.
Ex:
Table 1 --> Table_1
I was wondering if this is possible. I know it's possible to do this for columns but I was wondering if someone could write me something for tables. I don't use PhpMyAdmin very often, but I installed it in this case becuase it works easily.
I'm not sure if you could do this in a stored procedure, but it is easy enough to have a query generate a script for you:
SELECT CONCAT('RENAME TABLE `'
, table_name
, '` TO `'
, REPLACE(table_name, ' ', '_')
, '`;'
) AS renameQuery
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mySchema' AND TABLE_NAME LIKE '% %'
;
You could run a query like this to generate the SQL that will perform a rename:
SELECT CONCAT('RENAME TABLE ', table_name, ' TO ' , REPLACE(table_name, ' ', '_') , ';')
FROM information_schema.tables
WHERE table_schema = 'your_schema_name';
Remember to substitute your_schema_name for whatever your database is called.
To run the query in phpMyAdmin you can click the SQL tab at the top of the window, then paste the SQL into the box. The result of the above query will be SQL generated based off of the existing table names. Just copy this resulting SQL back into the textbox and run it again to perform the renames.
You can also rename all table with one command:
SELECT
CONCAT('RENAME TABLE '
,GROUP_CONCAT(
CONCAT('`',TABLE_NAME,'` TO ', REPLACE(TABLE_NAME,' ','_'))
SEPARATOR ', '),';') AS query
FROM information_schema.Tables
WHERE TABLE_SCHEMA = 'yourschema'
AND TABLE_NAME LIKE '% %';
sample
MariaDB [yourschema]> SELECT CONCAT('RENAME TABLE ' ,GROUP_CONCAT( CONCAT('`',TABLE_NAME,'` TO ', REPLACE(TABLE_NAME,' ','_')) SEPARATOR ', '),';') AS query FROM information_schema.Tables WHERE TABLE_SCHEMA = 'yourschema' AND TABLE_NAME LIKE '% %';
+--------------------------------------------------------------------------------------+
| query |
+--------------------------------------------------------------------------------------+
| RENAME TABLE `esercizio 1` TO esercizio_1, `my_table 1` TO my_table_1, `t 1` TO t_1; |
+--------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
MariaDB [yourschema]>

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.

Mysql UNION with dynamic query

i have the following problem. I inherited a software that uses a database prefix for every customer.
All tables have the same structure and columns. For a data migration to new version i want to union all these tables
and set a customer foreign key instead and get rid of all the subtables. i'm looking for a way to create
a view for this task because i also want to stay backwards compatible for now.
I found this dynamic query which seems to do what i want
but i can't execute on my mysql server. I assume it was written for another sql server.
The table name structure is (about 80 customer tables):
customer1_faxe
customer2_faxe
customer3_faxe
customer4_faxe
...
How would you approach this problem?
DECLARE #SelectClause VARCHAR(100) = 'SELECT *'
,#Query VARCHAR(1000) = ''
SELECT #Query = #Query + #SelectClause + ' FROM ' + TABLE_NAME + ' UNION ALL '
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE '%_faxe'
SELECT #Query = LEFT(#Query, LEN(#Query) - LEN(' UNION ALL '))
EXEC (#Query)
This query is using SQL Server syntax. You need something like this:
declare #SelectClause varchar(8000);
declare #Query varchar(8000);
set #SelectClause = 'SELECT *';
SELECT #Query := group_concat(#SelectClause, ' FROM ', TABLE_NAME SEPARATOR ' UNION ALL ')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE '%_faxe';
prepare stmt from #Query;
execute stmt;
Note that the group_concat() with separator simplifies the logic.

How to change all table prefix in a single query

I am pretty amateur in mysql..can you please tell me how can I change table prefixes of my whole database in a single query... I can do it manually, but its quite time consuming to change all the tables prefixes. Please help me out. Like isc_administrator_log to cus_administrator_log means isc_ to cus_
I found these two solutions but do not understand either of them.
SELECT
GROUP_CONCAT('RENAME TABLE `', TABLE_SCHEMA, '`.`', TABLE_NAME, '` TO `',
TABLE_SCHEMA, '`.`prefix_', TABLE_NAME, '`;' SEPARATOR ' ')
FROM `TABLES` WHERE `TABLE_SCHEMA` = "test";
and
SELECT
CONCAT('RENAME TABLE ', GROUP_CONCAT('`', TABLE_SCHEMA, '`.`', TABLE_NAME,
'` TO `', TABLE_SCHEMA, '`.`prefix_', TABLE_NAME, '`')) AS q
FROM
`information_schema`.`Tables` WHERE TABLE_SCHEMA='test';
Both statements generate strings which happen to be SQL statements that you can then copy/paste at your prompt to rename your tables.
Just replace the following two strings with the actual values your need:
prefix_ : the prefix you want to add
'test' : the name of the database containing the tables you want to rename
Both statements are almost identical, the only difference is that information_schema is not explicitely mentioned in the first statement. Therefore the first statement must be run from the information_schema database (issue USE information_schema beforehands).
phpmyadmin : select database ; tab structure => Check all => (with selected list) select add prefix to table .
(is not query but it works)
You can do Dynamic SQL Query For MySQL 5.0.13
delimiter //
CREATE PROCEDURE dynamic(IN tbl CHAR(64), IN col CHAR(64))
BEGIN
SET #s = CONCAT('SELECT 'RENAME TABLE ',
GROUP_CONCAT('', TABLE_SCHEMA, ''.'', TABLE_NAME,
' TO ', TABLE_SCHEMA, ''='.prefix_''', TABLE_NAME, '')) AS q
FROM
information_schema.Tables WHERE TABLE_SCHEMA='test'';;'
PREPARE stmt FROM #s;
EXECUTE stmt;
END
//
delimiter ;
Got the Reference from here