MySQL database name as alias for query between multiple databases - php

mysqli_query("SELECT login.validto,
(SELECT databases.databasename FROM DB1.databases WHERE databases.ID = login.ID ORDER BY databases.lastused DESC LIMIT 1) AS dbname,
(SELECT users.username FROM dbname.users WHERE users.ID = '2') AS username
FROM DB1.login
WHERE login.token = 'abc13def456';");
Is it possible to use the alias dbname as database for the subquery instead of using 2 separate queries from PHP?
Im using 1 database to handle all the logins and then we use X databases to hold all the customers data, one database for each customer and later on it should be possible for the customers to change between the databases.
Im curently getting error:
Error Code: 1142
SELECT command denied to user 'myMySQLuser'#'myMySQLhost' for table 'users'
Changing the dbname to the real database name works just fine and the dbname and real database is the same, but i want to make 1 query instead of 2 from my PHP script.

It is possible to use the existing solution to create a procedure on MySQL server that will be called from your PHP appliation.
CREATE PROCEDURE my_proc()
BEGIN
DECLARE #dbname, #username VARCHAR(25);
# Set #dbname value
SELECT databases.databasename INTO #dbname FROM DB1.databases WHERE databases.ID = login.ID ORDER BY databases.lastused DESC LIMIT 1;
# Create query to set #username value from required database
SET #user_query = CONCAT('SELECT users.username INTO #username FROM ', #dbname, '.users WHERE users.ID =2;');
PREPARE stmt FROM #user_query;
EXECUTE stmt; # set #username value
DEALLOCATE PREPARE stmt;
# Main query
SELECT validto, #dbname, #username
FROM FROM DB1.login WHERE login.token = 'abc13def456';
END
Also you can call the procedure with parameters that you need. Then you will be able to use simple PHP statement to get required data.

Related

SQL: How to string together multiple queries using an inner join?

I'm designing a search engine which will sift through data in a database. I have 2 tables in my database:
Members:= `MemberID|Firstname|Secondname|Member_Type|Skills|Marital Status`
Schedule:= `ScheduleID|MemberID (foreign key)|six_am|seven_am|...|nine_pm`
(where the values for six_am|seven_am|...|nine_pm are boolean values and represent availablity)
My question is if there's a way to create a single SQL query similar to:
SELECT * FROM members1 (WHERE $x LIKE $firstname OR $x LIKE SecondName...) INNER JOIN schedules ON (members1.members_id = schedules.member_id)
WHERE eleven_am=1 OR twelve_pm=1
This way, I can enter a single query instead of multiple ones.
You can use prepared statements:
SET #query = 'build your own query in any way';
PREPARE stmt FROM #query;
SET #id = 4; -- here you can add variable for safe inserting to the query. if you want to
EXECUTE prepared_query USING #id;
DEALLOCATE PREPARE stmt;
The #query can be built by some server side language (PHP for example) or by string manipulations in pure SQL.
Afterwards you send the "template" to execution.
If you'll provide more details I can build more exact example.
But this is an idea.

Wrong results when query run in Symfony as opposed to PHPMyAdmin

I have the following code in a controller. The query given runs on a MediaWiki database:
// Grab the connection to the replica database (which is separate from the above)
$conn = $this->get('doctrine')->getManager("replicas")->getConnection();
// Prepare the query and execute
$resultQuery = $conn->prepare( "
SELECT 'id' as source, user_id as value FROM $dbName.user WHERE user_name = :username
UNION
SELECT 'arch' as source, COUNT(*) AS value FROM $dbName.archive_userindex WHERE ar_user_text = :username
UNION
SELECT 'rev' as source, COUNT(*) AS value FROM $dbName.revision_userindex WHERE rev_user_text = :username
UNION
SELECT 'groups' as source, ug_group as value FROM $dbName.user_groups JOIN user on user_id = ug_user WHERE user_name = :username
");
$resultQuery->bindParam("username", $username);
$resultQuery->execute();
(I know my SQL isn't efficient, it's legacy code that I'm working on cleaning up)
The fourth query is the focus of this question. When the query is run in PHPMyAdmin or MySQLWorkbench it returns the correct results. However, when run in Symfony sometimes it returns the improper results. How can I ensure that it returns the correct results?
(Full full code: https://github.com/Matthewrbowker/xtools-rebirth/blob/master/src/AppBundle/Controller/SimpleEditCounterController.php#L95)
Figured out my question. One thing that wasn't noted was the fact that I wound up selecting the right database name out of a table. This was stored in the variable $dbName. However, it is possible for $dbName to be different than the database that I connected to from paramaters.yml.
Note:
JOIN user on user_id
This portion of the query was missing $dbName. To fix, just add the variable. Like so:
JOIN $dbName.user on user_id

How to insert data in SQL temporary table from stored procedure in one query using PHP and drop table after getting resultset?

I have to execute these queries in PHP to get the result
CREATE TABLE #tempDept(deptid int)
INSERT INTO #tempDept
EXEC sprinter_DeptHier1 22;
# This will create a temporary table and insert the result of stored procedure into the temp table
select *
from sprinter_leave_request slr
where slr.id not in (select lr.leave_request_id
from leave_approver lr
where lr.approver_id = 980)
// get userid from session and userid in (select userid from userinfo
where defaultdeptid in (select deptid from #tempDept)) and slr.userid
<> 980 order by userid;
# This query will get the result from temp table
And after getting the result I have to drop the table before next transition occurs.
Kindly help me out to solve the issue, I have to execute the query as same as in the question.
I tried so but have no luck.

Prepared statement - cross table update

I am attempting to use a prepared statement in combination with a cross table update. I have prepared a sample script that is representative of our larger database. This first section does what I want without a prepared statement, but I am hoping to avoid copy/pasting this for every column of my data.
SET SESSION group_concat_max_len = 1000000000;
drop table if exists update_test;
create table update_test(
time_index decimal(12,4),
a varchar(20),
b varchar(20),
c varchar(20));
insert into update_test(time_index) values(20150101.0000),(20150101.0015),(20150101.0030);
drop table if exists energy_values;
create table energy_values(
time_stamp decimal(12,4),
site_id varchar(5),
energy int);
insert into energy_values
values(20150101.0000,'a',100),(20150101.0000,'b',200),(20150101.0000,'c',300),
(20150101.0015,'a',400),(20150101.0015,'b',500),(20150101.0015,'c',600),
(20150101.0030,'a',700),(20150101.0030,'b',800),(20150101.0030,'c',900);
drop table if exists update_test_sites;
create table update_Test_sites(
sites varchar(5));
insert into update_test_sites values
('a'),('b'),('c');
update update_test, energy_values, update_test_sites
set update_test.a=energy_values.energy
where update_test.time_index = energy_values.time_stamp
and energy_values.site_id ='a';
update update_test, energy_values, update_test_sites
set update_test.b=energy_values.energy
where update_test.time_index = energy_values.time_stamp
and energy_values.site_id ='b';
update update_test, energy_values, update_test_sites
set update_test.c=energy_values.energy
where update_test.time_index = energy_values.time_stamp
and energy_values.site_id ='c';
select * from update_test;
Which is why I have attempted something like this as a replacement for the update functions. However, I often get a syntax error report. Can anyone identify where I am going wrong? It would be much appreciated!
SELECT
concat(
'update update_test, energy_values, update_test_sites
set update_test.',sites,'=energy_values.energy
where update_test.time_index = energy_values.time_stamp
and energy_values.site_id = ',sites,';
select * from update_test;')
from update_test_sites
where sites = 'a'
INTO #sql;
PREPARE stmt FROM #sql;
EXECUTE stmt;
I've never seen "SELECT INTO" work that way. In my experience, it is used like so:
SELECT [field_list] INTO [variable_list]
FROM [some_table]
[etc...]
I don't think it can be used to store a resultset like it appears you are attempting.
With some tweaking and doing this in a stored procedure, you could use a cursor to iterate over the results to prepare and execute each generated statement individually.

MySQL - Passing Dynamic Column Names in Stored Procedures Using Prepared Statements

I've been pulling my hair out over this for the last 12 hours. I am trying to create a stored procedure to display the results of a search from a PHP page. There are a couple column names that are dynamic and are passed in by the php page. I thought i could use a prepared statement to get around this, but it doesn't seem to be working. When i run the SP below in phpMyAdmin, i get zero rows returned.
CREATE DEFINER=`test`#`localhost` PROCEDURE `AllLoads7`(
IN p_search_field VARCHAR(25),
IN p_search_for VARCHAR(250),
IN p_load_status INT,
IN p_date_field VARCHAR(25),
IN p_startDate DATETIME,
IN p_endDate DATETIME,
IN p_employeeID INT,
IN p_OrderBy VARCHAR(25)
)
begin
SET #GetLoads = CONCAT("SELECT * FROM loads_contacts WHERE ",p_search_field," LIKE '%",p_search_for,"%' AND status LIKE '%",p_load_status,"%' AND ",p_date_field," BETWEEN '",p_startDate,"' AND '",p_endDate,"' AND company_id IN(SELECT company_id FROM employees_companies WHERE employee_id = ",p_employeeID,") ORDER BY ",p_OrderBy);
PREPARE stmt FROM #GetLoads;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
end
Here is how phpMyAdmin is calling it
SET #p0='pronumber';
SET #p1='1';
SET #p2='1';
SET #p3='dateCreated';
SET #p4='2010-01-01';
SET #p5='2014-01-01';
SET #p6='2';
SET #p7='status';
CALL `AllLoads7`(#p0, #p1, #p2, #p3, #p4, #p5, #p6, #p7);
if I add "SELECT #GetLoads;" to the SP, i get the following query. If i run that query against my database, i get the expected rows returned. This tells me that the SQL is being generated correctly, it just seems that i'm not doing something quite right to execute the prepared statement
#GetLoads
SELECT * FROM loads_contacts WHERE pronumber LIKE '%1%' AND status LIKE '%1%' AND dateCreated BETWEEN '2010-01-01 00:00:00' AND '2014-01-01 00:00:00' AND company_id IN(SELECT company_id FROM employees_companies WHERE employee_id = 2) ORDER BY status

Categories