Subquerying MYSQL to select All Databases from server - mysql

I've checked this topic before asking, and I found it was helpful just in a certain point, and now it's not enough.
I have a lot of databases in a MariaDB server, and one of the registered views is broken, giving me "Invalid references" error.
What I need is to find out what View is broken, considering that this error is preventing me to run my Backup routine, and MariaDB log shows only "Database (Got error: 1049) (Locktable)"
Now that I have a list of my views, is there any way to "select *" all of them, in different databases?
I've tried something like this:
select * from TABLE_SCHEMA where (select TABLE_SCHEMA,TABLE_NAME from information_schema.tables where TABLE_TYPE like 'VIEW');
But I know it will not work since I'm not providing a specific database.
I think a Inner-Join would solve this case, but I can't figure out how to accomplish it...
By the way, if there's a better approach to find what View is defective, I would appreciate it.
Thank you in advance!

Since the only answer was removed by it's contributor, I've developed a ugly but effective workaround:
I've created a file with both Database and View names, using query provided below:
mysql -p*** -e "SELECT TABLE_SCHEMA, TABLE_NAME FROM information_schema.`TABLES` WHERE TABLE_TYPE LIKE 'VIEW'" > views.txt
This saves to file "views.txt" the flow with the information I need to run a basic Select in a View, so I did the following:
while IFS= read -r line; do mysql -p*** -e "select * from $(echo $line | awk '{print $1}').$(echo $line | awk '{print $2}') LIMIT 1" 2>> errors.txt; echo $line >> errors.txt; done < views.txt
I know it's ugly, but it will run a "select *" in every database.table or database.view listed in "views.txt", returning only first line of this query.
It provided me a effective test in my server, which showed me what view was broken:
ERROR 1146 (42S02) at line 1: Table '.' doesn't exist
If you're facing similar problems, I hope you may find a better way to solve this.

Related

Custom #! to run file of SQL commands

I am looking for a way to have a simple way to execute SQL commands. One attempt is to make a custom #! script but I am not sure how to do this either.
If I do something like:
#!/bin/cat -n
select
col1
from
table;
I get output like
1 #!/bin/cat -n
2 select
3 col1
4 from
5 table;
Which makes me think I could be close.
But when I create a script like runsql.sh
#!/bin/bash
cat -n
./some_sql.sh: line 2: syntax error near unexpected token `newline'
./some_sql.sh: line 2: `select'
This is my attempt at being able to execute sql files. Is there someway people are doing this that I am not doing?
Thank you
try it:
mysql -e "YOUR_SQL_COMMAND"
for large command try it (i dont test but need work):
sqlCommand=$(cat <<EOF
This is large
Sql command
This is line three.
EOF
)
mysql < $sqlCommand

Detect and delete line break directly out of mysql query

im trying to detect and delete a line break out of a subject (called m.subject) mail information retrieved via CONCAT out of a mysql database.
That said, the linebreak may or may not occur in the subject and therefore must be detected.
My query looks like this:
mysql --default-character-set=utf8 -h $DB_HOST -D $TARGET -u $DB_USER -p$DB_PW -N -r -e "SELECT CONCAT(m.one,';',m.two,';',m.three,';',m.subject,';',m.four';',m.five,';',(SELECT CONCAT(special_one) FROM special_$SQL_TABLE WHERE msg_id = m.six ORDER BY time DESC LIMIT 1)) FROM mails_$SQL_TABLE m WHERE m.rtime BETWEEN $START AND $END AND m.seven = 1 AND m.eight IN (2);"
I tried to delete it afterwards, but getting in performance trouble due to several while operations on all lines already. Is there an easy way to detect and cut it directly via the CONCAT buildup? It is crucial to retrieve only one line after extraction for me.
Updating/changing the database is not an option for me, as I only want to read the current state.

Need to display alternative text when query results return no match

My script cycles through multiple environments and if a user is found, it prints out their ID. The desired output is as follows:
environment1
<user_id>
However, my script is currently working to print out every environment even if there isn't a user id, like follows:
environment1
<user_id>
environment2
environment3
environment4
<user_id>
I would like the code to print out "NO USER FOUND" if the user_id does not exist, rather than excluding the environment altogether.
The code below is what is being utilized:
#log it all
{
echo "environment"
sshpass -p $ldappw ssh $ldapuser#12.345.67.89 'mysql --skip-column-names -hhost -u user -ppassword database -e \
"select user_id from users where first like '"'%${first_name}%' and last like '%${last_name}%';"'"'
} > $log
Any help would be much appreciated for this issue. Unfortunately I'm just beginning to learn more advanced MySQL and Linux command line tools and am not quite proficient enough to know how to handle this problem.
may be
select ifnull(user_id,'NO USER FOUND') from users where first like '"'%${first_name}%' and last like '%${last_name}%';

Using MySQL in Powershell, how do I pipe the results of my script into a csv file?

In PowerShell, how do I execute my mysql script so that the results are piped into a csv file? The results of this script is just a small set of columns that I would like copied into a csv file.
I can have it go directly to the shell by doing:
mysql> source myscript.sql
And I have tried various little things like:
mysql> source myscript.sql > mysql.out
mysql> source myscript.sql > mysql.csv
in infinite variation, and I just get errors. My db connections is alright because I can do basic table queries from the command line etc... I haven't been able to find a solution on the web so far either...
Any help would be really appreciated!
You seem to not be running powershell, but the mysql command line tool (perhaps you started it in a powershell console though.)
Note also that the mysql command line tool cannot export directly to csv.
However, to redirect the output to a file just run
mysql mydb < myscript.sql >mysql.out
or e.g.
echo select * from mytable | mysql mydb >mysql.out
(and whatever arguments to mysql you need, like username, hostname)
Are you looking for SELECT INTO OUTFILE ? dev.mysql.com/doc/refman/5.1/en/select.html – Pekka 19 hours ago
Yep. Select into outfile worked! But to make sure you get column names you also need to do something like:
select *
from
(
select
a,
b,
c
)
Union ALL
(Select *
from actual)

dumping data from views in mysql

i have a view and want to extract its data into a file that has create table statement as well data.
i know that mysqldump doesn't work on views.
Obviously, there isn't an automated way to generate the CREATE TABLE statement of a table that does not exist. So you basically have two options:
Create an actual table, dump it and remove it afterwards.
Write a lot of code to analyse the view and underlying tables and generate the appropriate SQL.
First option is not optimal at all but it's easy to implement:
CREATE TABLE my_table AS
SELECT *
FROM my_view
You can now dump the table with mysqldump. When you're done:
DROP TABLE my_table
Second option can be as optimal as you need but it can get pretty complicate and it depends a lot on your actual needs and tool availability. However, if performance is an issue you can combine both approaches in a quick and dirty trick:
CREATE TABLE my_table AS
SELECT *
FROM my_view
LIMIT 1;
SHOW CREATE TABLE my_table;
Now, you use your favourite language to read values from my_view and build the appropriate INSERT INTO code. Finally:
DROP TABLE my_table;
In any case, feel free to explain why you need to obtain SQL code from views and we may be able to find better solutions.
Use SELECT ... INTO OUTFILE to create a dump of the data.
I have written a bash function to export the "structure" and data of a VIEW without creating a full copy of the data. I tested it with MySQL 5.6 on a CentOS 7 server. It properly takes into account columns with JSON values and strings like "O'Mally", though you may need to tweak it further for other special cases.
For the sake of brevity, I did not make it robust in terms of error checks or anything else.
function export_data_from_view
{
local DB_HOST=$1
local SCHEMA=$2
local VIEW=$3
local TMP_TABLE_NAME="view_as_table_$RANDOM"
local SQL1="
create table $TMP_TABLE_NAME as
(select * from $VIEW where 1=0);
show create table $TMP_TABLE_NAME \G
"
# Create an empty table with the structure of all columns in the VIEW.
# Display the structure. Delete lines not needed.
local STRUCT=$(
mysql -h $DB_HOST -BANnq -e "$SQL1" $SCHEMA |
egrep -v "\*\*\*.* row \*\*\*|^${TMP_TABLE_NAME}$" |
sed "s/$TMP_TABLE_NAME/$VIEW/"
)
echo
echo "$STRUCT;"
echo
local SQL2="
select concat( 'quote( ', column_name, ' ),' )
from information_schema.columns
where table_schema = '$SCHEMA'
and table_name = '$VIEW'
order by ORDINAL_POSITION
"
local COL_LIST=$(mysql -h $DB_HOST -BANnq -e "$SQL2")
# Remove the last comma from COL_LIST.
local COL_LIST=${COL_LIST%,}
local SQL3="select $COL_LIST from $VIEW"
local INSERT_STR="insert into $VIEW values "
# Fix quoting issues to produce executeable INSERT statements.
# \x27 is the single quote.
# \x5C is the back slash.
mysql -h $DB_HOST -BANnq -e "$SQL3" $SCHEMA |
sed '
s/\t/,/g; # Change each TAB to a comma.
s/\x5C\x5C\x27/\x5C\x27/g; # Change each back-back-single-quote to a back-single-quote.
s/\x27NULL\x27/NULL/g; # Remove quotes from around real NULL values.
s/\x27\x27{/\x27{/g; # Remove extra quotes from the beginning of a JSON value.
s/}\x27\x27/}\x27/g; # Remove extra quotes from the end of a JSON value.
' |
awk -v insert="$INSERT_STR" '{print insert "( " $0 " );"}'
local SQL4="drop table if exists $TMP_TABLE_NAME"
mysql -h $DB_HOST -BANnq -e "$SQL4" $SCHEMA
echo
}