Simple way to print structured SQL SELECT in bash - mysql

I'm trying to echo the output of a SELECT request in bash, in a structured form with column names. The issue is that i cannot do it properly with more than 2 fields or if the value is larger that the column name.
Example :
My table looks like this : value1 value2
If i do in bash : echo "select value1, value2 from table" | mysql -uUSER -pPASS
The result looks like this in bash :
value1 value2
a d
b e
c f
Now if i have 3 fields or a large value the result looks like this :
value1 value2 value3
aaaaaaaaa ddddddddddd ggg
bbbb eeeeeeeee hhhh
ccccccc fffffffff iiii
Is there a simple way to have a structured result ? I mean with column names correctly spaced? I know it is possible to do it with a sort to get the largest value and add the number of spaces needed but it seems to be too much for a simple problem like this.
Do you have an idea? Thanks !

Use the mysql -e option to execute your query, and -t to print table output to stdout:
mysql -uUSER -t -e "select value1, value2, value3 from table" -pPASS
Your output will look something like this:
+-----------+-------------+--------+
| value1 | value2 | value3 |
+-----------+-------------+--------+
| aaaaaaaaa | ddddddddddd | ggg |
| bbbb | eeeeeeeee | hhhh |
| ccccccc | fffffffff | iiii |
+-----------+-------------+--------+
From the mysql manpage:
--execute=statement, -e statement
Execute the statement and quit. The default output format is like that produced with --batch. See Section 4.2.3.1, “Using Options on
the Command Line”, for some examples. With this option, mysql does not use the history file.
and
-table, -t
Display output in table format. This is the default for interactive use, but can be used to produce table output in batch mode.

echo "select value1, value2 from table" | mysql -uUSER -pPASS | column -t

A good way to do this is By Not Using Echo to just print Everything to Webpage, Instead you need to assign Each with an Array Variable.
will be something like this :
int x[50];
x[i] = $value // which is from SELECT Query
i++
and put it in a Loop, so the result every time will be Stored in a new Location for Array. once you have saved all your results in an array, it will be much easier for you to organize, you can use Table in HTML
<table />
and Organize it to make it efficient for you to easily put the array of the variable in a loop, so basically you will have 2 loops. 1st loop to assign array to database attributes, Second Loop will be for Printing inside the table of HTML.

Related

MySQL query splitting unexpectedly in Bash Script

I am having issues and not understanding what the underlying cause is.
I have a table that has these three fields:
______________________________________________
| cid | order_id | TxRefNum |
----------------------------------------------
I am making a simple call in my bash script (there is literally no other code to start with)
#!/bin/bash
mysql --login-path=main-data -e "SELECT
cid,
order_id,
TxRefNum
FROM database.orders_temp" |
while read this that other; do
echo "$this || $that || $other"
done
I would expect to see the following:
__________________________________________________________
| 29 | F0VIc - CHATEAU ROOFIN | 5555555 |
----------------------------------------------------------
Instead my script is splitting the string $that into two different strings .. The echo is actually:
___________________________________________________
| 29 | F0VIc | - CHATEAU ROOFIN |
---------------------------------------------------
Do I have to set a delimiter when setting my variables in my while loop?? I am truly stumped!!
Getting output from the mysql command formatted in an intelligent way is problematic. In your case bash is interpreting the as a delimiter. You need to split a different way. I was able to get this working. You'll note the | in the query as well at the IFS line at the tope
#!/bin/bash
IFS='|' # set the delimiter
mysql --login-path=main-data -e "SELECT
29 as cid, '|',
'F0VIc - CHATEAU ROOFIN' as order_id,
'|',
5555555 as TxRefNum
FROM dual" |
while read this that other; do
echo "$this || $that || $other"
done

Read MySQL result from shell script

at first, I am a very new on shell scripting, so please don't shoot me !! :)
What I try to do. I have a multi-site WordPress installation, and I like to write a script that will be able to export specific tables from the schema either by passing the site id as argument in shell script, or by set an option to export all selected the tables of the schema.
The WordPress, in order to recognize which table set is for which site, changes the prefix of each table set. So In example does the following :
wp_options
wp_1_options
...
wp_x_options
In addition, the WordPress store the blog id in a special table called wp_blogs
So, from my shell script I run the following code :
mysql -uUSER -pPASS -e 'SELECT `blog_id` AS `ID`, `path` AS `Slug` FROM `wp`.`wp_blogs`'
and I am getting the following results
+----+---------------------------+
| ID | Slug |
+----+---------------------------+
| 1 | / |
| 2 | /site-2-slug/ |
| 4 | /site-4-slug/ |
| 5 | /site-5-slug/ |
| 6 | /site-6-slug/ |
| 7 | /site-7-slug/ |
| 8 | /site-8-slug/ |
| 9 | /site-9-slug/ |
| 10 | /site-10-slug/ |
+----+---------------------------+
So, now the actual question is, how can I parse the MySql result line by line, in order to get the ID and the Slug information ?
Side note 1 : The whole script has been generated and run's somehow manually. I need now this information in order to automate even farther the exporting script.
*Side note 2 : The MySql executed via the Vagrant ssh like the following line : *
sudo vagrant ssh --command "mysql -uroot -proot -e 'SELECT blog_id FROM wp.wp_blogs'"
You could save the result in a file using INTO like below:
SELECT blog_id, path FROM wp.wp_blogs
INTO OUTFILE '/tmp/blogs.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
And then you could process it line by line either usingsed/awk/simple while loop. Say you want to search for site and replace it with mysite, you could do something like:
awk -F',' '{print "Id: " $1 ", path: "$2}' /tmp/blogs.csv ##or simply cat the file.

How can I suppress column header output for a single SQL statement?

I'm executing some SQL statements in batch (using the mysql command-line binary). I want one of my several SELECT statements to not print the column headers, just the selected records. Is this possible?
Invoke mysql with the -N (the alias for -N is --skip-column-names) option:
mysql -N ...
use testdb;
select * from names;
+------+-------+
| 1 | pete |
| 2 | john |
| 3 | mike |
+------+-------+
3 rows in set (0.00 sec)
Credit to ErichBSchulz for pointing out the -N alias.
To remove the grid (the vertical and horizontal lines) around the results use -s (--silent). Columns are separated with a TAB character.
mysql -s ...
use testdb;
select * from names;
id name
1 pete
2 john
3 mike
To output the data with no headers and no grid just use both -s and -N.
mysql -sN ...
You can fake it like this:
-- with column headings
select column1, column2 from some_table;
-- without column headings
select column1 as '', column2 as '' from some_table;
A good reason to "... want ... SELECT statements to not print the column headers..." is for documenting output.
Thanks to #tom_warfield I do this:
select "Relevant details from Stock Entry." as ""\G
select
SE.name
, SED.item_code
, SED.s_warehouse
, SED.t_warehouse
, REPLACE(SED.serial_no,'\n',', ') as serial_no
from
`tabStock Entry` SE left join `tabStock Entry Detail` SED
:
:
My output then looks like this:
*************************** 1. row ***************************
: Relevant details from Stock Entry.
+--------------------+-------------------------------+--------------------------+----------------------------+---------------------------------------------------------------------------------------------------------------------+
| name | item_code | s_warehouse | t_warehouse | serial_no |
Note that "\G" instead of ";" outputs one attribute per line, rather than one row per line.

pdi spoon ms-access concat

Suppose I have this table named table1:
| f1| f2 |
--------------
| 1 | str1 |
| 1 | str2 |
| 2 | str3 |
| 3 | str4 |
| 3 | str5 |
I wanted to do something like:
Select f1, group_concat(f2) from table1
this is in mysql, I am working with ms-access! And get the result:
| 1 | str1,str2|
| 2 | str3 |
| 3 | str4,str5|
So I searched for a function in ms-access that would do the same and found it! xD
The problem is that everyday I have to download some database in ms-access, create the function to concat there, and then create a new table with those concated values.
I wanted to incorporate that process in the Pentaho Data Integration spoon transformations, that I use after all this work.
So what I want is a way to define a ms-access function in the PDI spoon, or some way to combine steps that would emulate the group_concat from mysql.
Simple - Query from access, and use the "group by" step to do your group_concat - there is an option to concatenate fields separated by , or any string of your choice.
Dont forget that the stream must be sorted by whatever you're grouping by unless you use the memory group by step.
A simple way is you move your data in ms-access to mysql with the same structure (mysql DB structure = ms-access DB structure), then execute your "Select f1, group_concat(f2) from table1". For details follow this below steps :
Create transformation A to move/transfer your ms-access data to mysql
Create transformation B to execute Select f1, group_concat(f2) from table1
Create job to execute transformation A and B (You must execute tranformation A before B)

How can I store the output of a mysql command into variables using the shell?

I am using this command:
mysql -u user -ppassword database -e "select distinct entityName,entitySource from AccessControl"
The output is like this:
+-----------------------+--------------+
| entityName | entitySource |
+-----------------------+--------------+
| low | Native |
| high | Native |
| All Groups | AD |
| Help Ser vices Group | AD |
| DEFAULT_USER_GROUP | Native |
| SYSTEM | Native |
| DEFAULT_BA_USER_GROUP | Native |
| soUsersGrp | Native |
+-----------------------+--------------+
My question is: how can I dynamically create an array of variables to store the values entityName and entitySource? What I need to use is use every value of entityName and entitySource to update another table.
Earlier I was trying to store the output in a file and access each line using awk, but that doesn't help because one line may contain multiple words.
Sure, this can be done. I'd like to second the idea that piping mysql to mysql in the shell is awkward, but I understand why it might need to be done (such as when piping mysql to psql or whatever).
mysql -qrsNB -u user -p password database \
-e "select distinct entityName,entitySource from AccessControl" | \
while read record; do
NAME="`echo $record|cut -d' ' -f 1`" # that's a tab delimiter
SOURCE="`echo $record|cut -d' ' -f 2`" # also a tab delimiter
# your command with $NAME and $SOURCE goes here ...
COMMAND="select trousers from namesforpants where entityName='${NAME}'" # ...
echo $COMMAND | mysql # flags ...
done
the -rs flags trim your output down so that you don't have to grok that table thing it gives you, -q asks that the result not be buffered, -B asks for batch mode, and -N asks to not have column names.
What you do with those variables is up to you; probably I would compose statements in that loop and feed those to your subsequent process rather than worry about interpolation and quotes as you have mentioned some of your data has spaces in it. Or you can write/append to a file and then feed that to your subsequent process.
As usual, the manual is your friend. I'll be your friend, too, but the manpage is where the answers are to this stuff. :-)
#!/usr/bin/env bash
mysql -u user -ppassword database -e "select distinct entityName,entitySource from AccessControl" | while read name source; do
echo "entityName: $name, entitySource: $source"
done
Please check it, I fixed it through exec.
[wcuser#localhost]$ temp=`exec mysql -h10.10.8.36 --port=3306 -uwcuser -pwcuser#123 paycentral -e "select endVersion from script_execution_detail where releaseNo='Release1.0' and versionPrefix='PS'"|tail -1`
[wcuser#localhost]$ echo $temp
19