Can I check if a table exists before join? - mysql

I have the following problem. I have Table A and would like to join to table B if table B exists. Can this be done? I am only writing SQL in WorkBench to try achieve it.
I am aware I cannot use the EXISTS option as I have tried typing it out but it prompts for an error.
Any suggestions would be greatly appreciated.
Thanks.

I managed to do this using EXECUTE, so using a query that is only prepared at runtime:
SET #sqlCommand = IF(
EXISTS (SELECT column_name FROM information_schema.columns WHERE table_schema = '{{yourschemaname}}' AND table_name = '{{yourtablename}}' AND column_name = '{{yourcolumnname}}'),
'SELECT \'Yes! Good to go!\' as ColumnExists',
'SELECT \'Nope!\' as ColumnExists');
PREPARE executable FROM #sqlCommand;
EXECUTE executable;
Note that the two selects at the center (Yes!/No!) are the custom statements that are to be executed conditionally. So if the column exists, the first command is executed (select 'yes!'), otherwise the second one (select 'nope').
I got the hint from this discussion here.. have a look if you're looking for the MSSQL equivalent: https://ask.sqlservercentral.com/questions/97579/check-if-table-exists-in-join.html

Data manipulation language statements are typically written for a specific schema; you are assumed to know what the schema looks like when you issue the statement. So you don't generally have the capacity to ask whether a particular schema object exists or has a particular structure. You could however write a stored procedure that did different things depending upon the schema. You have the ability in a stored procedure to use conditional statements and to look in INFORMATION_SCHEMA.

Related

mysql) select values if table exists

I'm trying select all values if such table exists. If it doesn't exist, just leave it.
I'm trying to do this only in one MYSQL code. Not with the help of python or something.
SELECT CASE WHEN (SELECT count(*)
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = '{db0}' AND TABLE_NAME = '{table0}')=0
THEN 'None' ELSE (SELECT MAX({colname}) FROM {db0}.{table0}) END;
If i inject existing table name on it, it works well.
But if not , it shows the error sign that saying such table doesn't exist.(Table 'corps.060311' doesn't exist)
What should I do?
This cannot be achieved using a simple query because MySQL analyses the query as a whole before performing it: it is not a procedural language and the queries are never executed line by line.
To do what you want to do without help of any other language, you must use stored procedures: https://dev.mysql.com/doc/refman/8.0/en/create-procedure.html
So the first step is to add a new FUNCTION in your database that will contain the "if table exists" part (see https://dev.mysql.com/doc/refman/8.0/en/if.html for if statements) and will return the desired value based on the schema, table, and column provided as strings in input of the function.
Then you can use the FUNCTION in any query in your database.

Update multiple database/tables on one server

I'm using Workbench, I'm not an expert at SQL but always open to learning.
My goal is to Update multiple tables at once and have the Replace happen on all found results.
Something like:
SELECT * FROM *.*;
UPDATE *.* SET post_content = REPLACE(post_content,'data-exclude="direct"','');
But the syntax is wrong. I have 100+ databases that need to be updated so I'd rather not have to list each one out.
Also, if it helps, I'm editing the same table in each database, so if there's another way to go about this, awesome. The table has a different prefix in each database but always ends in: _posts
Thanks ahead of time!
As I noted in the comments, you will have to dynamically write out each UPDATE statement and then execute each dynamically generated statement. You can write a script or procedure to do that, or you can just write some SQL to identify databases/tables that contain the column name you are after and write out the UPDATE statements that way:
SELECT DISTINCT CONCAT('UPDATE `', TABLE_SCHEMA, '`.`', TABLE_NAME, '` SET post_content = REPLACE(post_content,''data-exclude="direct"'','''');') as statement
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME = 'post_content';
Or something like that... (haven't tested)
Then just copy/paste the results back into your sql client and execute.

CTE and tablename as parameter

In SQL Server 2008, I have stored procedure containing a CTE
;with t1 as (select * from db..tablename where …)
Select * from t1;
I want to use tablename as one of the stored procedure parameters.
Please note the size of T1 turns out to be too big to use something like
Exec(‘select * into #temptable from db..’+’tablename’+’ where …’)
There have been similar questions and answers but none of them seems to help.
Thanks
I love using CTE's. They are such a great utility!
For this particular problem might I suggest against it. Given that you are "transporting" a table worth of data to another stored proc I think you should handle it a bit differently.
Consider your first proc:
IF OBJECT_ID('SomeTempTable') IS NOT NULL DROP SomeTempTable;
SELECT
*
INTO SomeTempTable
FROM
YourOtherTable
EXEC YourSecondProcedureName
Please note you'll need to be mindfull of the scope you want for your table. I haven't included working code until you make that consideration. More information can be found here: Temp Table Scope
Also note that the "YourSecondProcedureName" does not take a table value now. Instead (and with the right scope) you can just call out of your temp table by name. Its also considered best practice to drop your temp tables when done though there are some mechanisms in sql server depending on version that can do some of it for you. Again scope scope scope.
Hope this helps!
Matt

How can I replace a string in a MySQL database for all tables in all fields in all rows?

I have a Moodle installation that I migrated to another server and I need to change several references to the old domain.
How can I replace a string for another string in MySQL for a given database searching all tables, all fields, and all rows?
I don't need to change the field names, just the values.
Related: How can I use mySQL replace() to replace strings in multiple records?
But the marked as answer solution implies I strongly type the table name and I need to fire this into an entire database, not manually work on each table running the script N times.
This may seem a bit ... ugly. But maybe simply dump the database to a sql/txt file, replace all strings and recreate the database using the modified dump.
You could run the following code to create all the udpate statements you would need to run to do your updates. It would update every field in every table within your database. You would need to run this code, and copy the results and run them.
WARNING - Be sure to test this in a test environment. You don't want any unpleasant surprises. Modify as needed.
SELECT concat('UPDATE ', TABLE_NAME, ' SET ', COLUMN_NAME, ' = REPLACE(', COLUMN_NAME, ', ''STRING_TO_REPLACE'', ''REPLACE_STRING'')')
FROM INFORMATION_SCHEMA.COLUMNS c
WHERE TABLE_SCHEMA = 'YOUR_DATABASE_NAME'
AND DATA_TYPE IN ('char', 'varchar')
;
I limited this to only char and varchar fields. You may need to add additional data types.
I would consider querying INFORMATION_SCHEMA.COLUMNS and dynamically searching the columns and tables. Try something like creating a cursor of all the columns and tables in the db:
DECLARE col_names CURSOR FOR
SELECT column_name, table_name
FROM INFORMATION_SCHEMA.COLUMNS
Then iterate through each of the columns in each of the tables and run dynamic/prepared sql to update where the string exists.
Here are a couple of good posts to get you in the right direction:
https://stackoverflow.com/a/4951354/1073631
https://stackoverflow.com/a/5728155/1073631

Drop all stored procedures in MySQL or using temporary stored procedures

Is there a statement that can drop all stored procedures in MySQL?
Alternatively (if the first one is not possible), is there such thing as temporary stored procedures in MySQL? Something similar to temporary tables?
I would have thought that this would do it, but I'm open to corrections:
(EDITED to incorporate a good point provided in the comments)
delete from mysql.proc WHERE db LIKE <yourDbName>;
(As pointed out by Balmipour in the comments below, it's a good idea to specify the database.)
I think it's valid to want to drop all procedures in a given database, otherwise in a long development cycle there's a danger of obsolete procedures and functions accumulating and muddying everything up.
Since DROP PROCEDURE and DROP FUNCTION does not allow sub selects, I thought it might be possible to perform the operation through another stored procedure, but alas, MySQL does not allow stored procedures to drop other stored procedures.
I tried to trick MySQL to to this anyway by creating prepared statements and thus separating the drop call somewhat from the stored procedure, but I've had no luck.
So therefore my only contribution is this select statement which creates a list of the statements needed to drop all stored procedures and functions.
SELECT
CONCAT('DROP ',ROUTINE_TYPE,' `',ROUTINE_SCHEMA,'`.`',ROUTINE_NAME,'`;') as stmt
FROM information_schema.ROUTINES;
This seems to drop the procedures...not sure about implications though
DELETE FROM mysql.proc WHERE db = 'Test' AND type = 'PROCEDURE';
I can almost get working a piece of code to drop all stored procs, but I think MySQL isn't letting me use a LOOP or a CURSOR outside of a stored procedure.
I can write a SQL file that counts the number of stored procedures for a given schema, and I have the code to iterate through the table and drop procedures, but I can't get it to run:
SELECT COUNT(ROUTINE_NAME)
INTO #remaining
FROM information_schema.ROUTINES
WHERE ROUTINE_SCHEMA = SCHEMA()
AND ROUTINE_TYPE = 'FUNCTION';
kill_loop: LOOP
IF #remaining < 1 THEN
LEAVE kill_loop;
END IF;
SELECT ROUTINE_NAME
INTO #cur_func_name
FROM information_schema.ROUTINES
WHERE ROUTINE_SCHEMA = SCHEMA()
AND ROUTINE_TYPE = 'FUNCTION'
LIMIT 1;
DROP FUNCTION #cur_func_name;
#remaining = #remaining - 1;
END LOOP;
I use select statement to display all Drop Procedure statements of a specific database in one cell. Then copy it to query window.
SET group_concat_max_len = 4096;
SELECT GROUP_CONCAT(Procedures SEPARATOR '; ') From (SELECT CONCAT(
"DROP PROCEDURE IF EXISTS `",SPECIFIC_NAME, '`') AS Procedures
FROM information_schema.ROUTINES R WHERE R.ROUTINE_TYPE = "PROCEDURE"
AND R.ROUTINE_SCHEMA = 'my_database_name') As CopyThis;
after the select statement which creates a list of the statements needed to drop all stored procedures and functions. You can avoid the manual work of copy pasting the listed queries as follows:
mysql>SELECT
CONCAT('DROP ',ROUTINE_TYPE,' `',ROUTINE_SCHEMA,'`.`',ROUTINE_NAME,'`;') as stmt
FROM information_schema.ROUTINES into outfile '/tmp/a.txt';
mysql> source /tmp/a.txt;
#user1070300's answer seems to work, but it looks like it can drop a lot of things.
A quick DESC mysql.proc; led me to add a WHERE to my request, so as to spare already existing MySQL procedures, which I had, of course, no reason to drop.
I executed DELETE FROM mysql.proc WHERE db NOT LIKE 'mysql';
If you have several bases and want to target only one, use DELETE FROM mysql.proc WHERE db LIKE '<yourDbName>' instead;
Btw, if like me, you are completely clearing your database and need to also drop your tables, you can use this linux shell script :
mysql -Nse 'show tables' DATABASE_NAME | while read table; do mysql -e "drop table $table" DATABASE_NAME; done
(see Truncate all tables in a MySQL database in one command? for more details)
Truncate all tables in a MySQL database in one command?