Fetch mysql data in bash, function read reads every sentence as variable - mysql

I trying to get variables from my db, I one value in db I've got 2 words, but command below treat it as 2 variables.
Is there any change to fetch it in my way ?
mysql -uroot -proot --database=symfony -se "SELECT cameras.source, cameras.name, investments.name, users.username FROM cameras JOIN investments ON investments.id = cameras.investment_id JOIN users ON users.id = investments.user_id;" | while read source camera investment username; do
mysql result :
| source | name | name | username |
+------------------------------------------------------------------------+--------------+------------+----------+
| rtsp://vlc:vlc#test/cam/realmonitor?channel=1&subtype=0 | camera 1 | investment | user |
+------------------------------------------------------------------------+--------------+------------+----------+
bash:
echo "source :"$source
echo "camera :" :$camera
echo "investments: " $investments
echo "username: " $username
result:
source :rtsp://vlc:vlc#test/cam/realmonitor?channel=1&subtype=0channel=1&subtype=0
camera : investment
investments: 1
username: investment username

for avoid the that thge space in camera.name is confused as a saperator you could replace the space with another char eg _
SELECT cameras.source
, replace(cameras.name, ' ', '_')
, investments.name, users.username
FROM cameras
JOIN investments ON investments.id = cameras.investment_id
JOIN users ON users.id = investments.user_id;

Related

SQL request with a joining condition

SELECT mairie.city, permission.permission
FROM permission , user_mairie, mairie
WHERE user_mairie.iduser = 1
AND user_mairie.idmairie = mairie.idmairie
CASE user_mairie.idrole
WHEN 2 THEN
JOIN user_permission
ON user_permission.idpermission = permission.idpermission
AND user_permission.iduser = user_mairie.iduser
END
ORDER BY mairie.idmairie, permission.idpermission
I'm trying to get the permissions of a specific user if this user has a specific role.
A "mairie" is a "town hall" in french.
A user can have different roles in different "mairie"s.
If the user on user_mairie has idrole = 2, then we have to go to the table "user_permission" to get it's permissions.
If the user on user_mairie has idrole = 1 then he is admin and he has ALL permissions, but the permissions are not written in user_permission (because user_permission is used only for idrole = 2).
What I want is for example :
if the user_mairie.idrole = 1 :
SELECT *
FROM permission
if the user_mairie.idrole = 2
SELECT *
FROM permission, user_permission
WHERE user_mairie.idrole = 2
AND user_mairie.iduser = user_permission.iduser
AND user_permission.idpermission = permission.idpermission
I could do this using my programming language and making 2 requests, but I'd like to know if in pure SQL, this issue is solvable.
Some datas:
Table permission:
idpermission | permission
1 | permission_1
2 | permission_2
3 | permission_3
Table user_mairie :
iduser | idmairie | idrole
1 | 1 | 1
1 | 2 | 2
Table user_permission :
iduser | idpermission | idmairie
1 | 1 | 2
1 | 3 | 2
Table mairie :
idmarie | city
1 | mairie_1
2 | mairie_2
The result I want (for a given iduser = 1) would be :
mairie_1 : permission_1, permission_2, permission_3
mairie_2 : permission_1, permission_3
Thanks for reading me.
SQL DEMO
First you start with all marie and all permissions
SELECT um.idrole, m.city, p.permission
FROM user_mairie um
JOIN mairie m
ON um.idmairie = m.idmairie
CROSS JOIN permission p
WHERE um.iduser = 1
Now you remove the permission you dont have
WHERE um.iduser = 1
AND ( um.idrole = 1 -- have all permission
OR EXISTS (SELECT up.idpermission
FROM user_permission up
WHERE up.iduser = um.iduser
AND up.idpermission = p.idpermission )
)
OUTPUT
I think you really want LEFT JOIN:
SELECT . . .
FROM user_mairie LEFT um
user_permission up
ON um.iduser = up.iduser LEFT JOIN
permission p
ON up.idpermission = p.idpermission OR
um.idrole = 1 ;
You may not want the condition on idrole.
This gets permissions only for id roles "2".
Notes:
List all the columns you want in the SELECT.
Learn to use proper, explicit, standard JOIN syntax. Never use commas in the FROM clause.
Table aliases make the query easier to write and to read.
Use LEFT JOIN so you can keep all the rows, even when there are no permissions.

Mysql Update user Balance SQL syntax Error

I want update an Users Balance but i dont know how i can do it.
With my code its dont work:
$sql = "UPDATE apiusers SET balance = balance - (product_price) WHERE username = (username);";
if(mysqli_query($link, $sql)){
echo "Records added successfully.";
} else{
echo "ERROR: Could not able to execute $sql. " . mysqli_error($link);
}
Table apiuser:
+-------------+
| Field |
+-------------+
| id |
| user |
| pass |
| balance |
| lastip |
| lastlogind |
| email |
| verification|
+-------------+
I would expect something like this:
update apiusers
set balance = balance - ? -- how much to change the balance
where userid = ?; -- which user to change it for
(Of course, I don't know how the users are identified.)
The ? is for parameters to pass in with. You should be using parameters, rather than stuffing the values into strings.
You forgot your equal
$sql = "UPDATE apiusers
SET balance = (balance - product_price)
WHERE user = \"".$username."\";";
\"username\", because " would close the string for $sql and with \" you prevent that.
You need a "Where", so you can update the column with the ID xy.

Perl and MySQL user input to select a row?

Suppose I have a simple database table that doesn't have an ID_KEY but has a name column. I want to display the output like this
+----+---------+
| | name |
+----+---------+
| 1 | dog |
| 2 | cat |
| 3 | penguin |
| 4 | lax |
| 5 | whale |
| 6 | ostrich |
+----+---------+
Then have a <STDIN> for like, say, 3 to select penguin. 3 is just the line number that appears when you do the select call.
Is there any way to do this, or is it only possible with an id key associated and then a subsequent select statement matching that id key?
I misunderstood you at first but I've caught on. But it doesn't make much sense, as when you're entering a number into a Perl program you won't be working with the MySQL command-line tool, and won't be able to see what numbers to enter..
What you need to do is to write your Perl program so that it prints all the name fields from the table together with a line number. Then your program can translate from an input animal number to its name because it knows what it printed.
Something like this would work. Of course you will have to set the name, IP address and credentials correctly so that DBI can connect to the database.
use strict;
use warnings;
use DBI;
my $dbh = DBI->connect(
'DBI:mysql:database=animal_test',
'username',
'password',
{ RaiseError => 1 },
);
my $names = map #$_, $dbh->selectall_arrayref('SELECT name FROM animals');
for my $i ( 0 .. $#$names ) {
printf "%3d: %s\n", $i+1, $names->[$i];
}
print "\n";
print "Enter animal number: ";
my $animal = <>;
chomp $animal;
my $name = $names->[$animal-1];
printf "Animal chosen is %s\n", $name;
Option 1 - You would have put a id field in the DB if you want to find by integer 3 because row 3 will not always be penguin from an SQL query.
Option 2 - Dump the data into and array or hash and use the index of that to find the item from with in the variable and not the DB when 3 is captured from STIN.
Just use query:
my $select = $dbh->prepare('
SET #id:=0;
SELECT name,
#id = #id+1
FROM table
');

Perl query and get column name

I need to make a query where I will be looking for a specific string through several columns and I need to know which column (name) contains the value that I need.
In the example below I need a query where I can ask which column contains the value 1000000000002101214 and that it returns f1. DB is MySQL and I need the programming to be done in Perl.
+---------------------+---------------------+---------------------+
| f1 | f2 | f3 |
+---------------------+---------------------+---------------------+
| 1000000000002101214 | 1000000000001989129 | 1000000000001881637 |
| 1000000000002080453 | 1000000000001968481 | 1000000000001862284 |
| 1000000000002085919 | 1000000000001973677 | 1000000000001866854 |
| 1000000000002075076 | 1000000000001963189 | 1000000000001857288 |
+---------------------+---------------------+---------------------+
I was able to find an almost-answer to my question from another site where I could get the column names of the fields in the table with the following:
my #cols = #{$sth->{NAME}}; # or NAME_lc if needed
while (#row = $sth->fetchrow_array) {
print "#row\n";
}
$sth->finish;
foreach ( #cols ) {
printf( "Note: col : %s\n", $_ );
}
The problem is partially resolved. In the example table I provided in the original question I needed to know on which column my answer resides, the query contains several OR statemens:
SELECT * FROM table WHERE (f1='1000000000002101214' OR f2='1000000000002101214' OR f3='1000000000002101214')
And I need the result to show that the column name where the number is located is f1. So....
Any thoughts?
I don't even know where to start
Check out Perl's DBI module. Read the documentation. You'll have to do something like below:
#!/usr/bin/perl
use strict;
use warnings;
use DBI;
#Connect to your database, provide id, password
my $dbh = DBI->connect('dbi:mysql:perltest','root','password') or die "Connection Error: $DBI::errstr\n";
#Write your query
my $sql = "select * from database_schema";
my $sth = $dbh->prepare($sql);
#Execute it
$sth->execute or die "SQL Error: $DBI::errstr\n";
#Fetch the value
while (my #row = $sth->fetchrow_array) {
#Do something with your result
print "#row\n";
}
If you are new to Perl then see: http://learn.perl.org/
Edit: Query to find out column name based on the value found in column.
Select 'f1'
from database_schema
where database_schema.f1 = 1000000000002101214
union
Select 'f2'
from database_schema
where database_schema.f2 = 1000000000002101214
union
Select 'f3'
from database_schema
where database_schema.f3 = 1000000000002101214

bash - SQL Query Outputs to variable

Im new in bash scripting.
I want to save sql-query outputs in variable, but
actually I must connect for every query to mysql with:
mysql -u $MYUSER -p$MYPASS -D database
and want to save every output in seperatly variable
sample query is: SELECT domain FROM domains WHERE user='$USER'
to
$variable1 = FIRST_OUTPUT
$variable2 = 2ND_OUTPUT
thank you
Taken from bash script - select from database into variable, you can read the query result into a variable.
Example
mysql> SELECT * FROM domains;
+-------+---------+
| user | domain |
+-------+---------+
| user1 | domain1 |
| user2 | domain2 |
| user3 | domain3 |
+-------+---------+
Usage
$ myvar=$(mysql -D$MYDB -u$MYUSER -p$MYPASS -se "SELECT domain FROM domains")
$ echo $myvar
domain1 domain2 domain3
echo is the bash command for output. You can then split $myvar into separate variables:
$ read var1 var2 var3 <<< $myvar
$ echo $var1
domain1
$ echo $var2
domain2
You can combine these two commands into a single one:
read var1 var2 var3 <<< $(mysql -D$MYDB -u$MYUSER -p$MYPASS -se "SELECT domain FROM domains")
It is possible to store the results into arrays (useful if you don't know how many records there):
$ read -ra vars <<< $(mysql -D$MYDB -u$MYUSER -p$MYPASS -se "SELECT domain FROM domains")
$ for i in "${vars[#]}"; do
$ echo $i
$ done
domain1
domain2
domain3
Another way of doing is:
dbquery=`mysql -D$MYDB -u$MYUSER -p$MYPASS -se "SELECT domain FROM domains"`
dbquery_array=( $( for i in $dbquery ; do echo $i ; done ) )
The first line stores all the output from the query in a varriable dbquery in a array-like-way. The second line converts the dbquery into an array dbquery_array with a simple for loop.
I did this
variable=mysql -u root -ppassworrd database << EOF
select MAX(variable) AS a from table where variable2 = 'SOMETEXT' AND day(datevalue) >= 22;
EOF
I hope it helps