How to run complex sql query in Laravel - mysql

I have some complex SQL which consists of a series of non-query statements, that make use of temporary tables in MySql, and then a SELECT statement at the end to return the result.
e.g
DROP TABLE IF EXISTS temp_foo;
CREATE TEMPORARY TABLE IF NOT EXISTS temp_foo AS (
SELECT *
FROM foo
);
SELECT * from temp_foo;
How can I run this all in the one DB call from Laravel and get the results of that last SELECT statment?
I've tried doing something like this in laravel, but it gives me a MySql syntax error, which is strange as that exact sql works ok when I run it directly in MySQl.
DB::select("
DROP TABLE IF EXISTS temp_foo;
CREATE TEMPORARY TABLE IF NOT EXISTS temp_foo AS (
SELECT *
FROM foo
);
SELECT * from temp_foo;
");
Any ideas on how can make this work?

You need to use DB::raw() to make your query work, for example:
DB::select(DB::raw("
DROP TABLE IF EXISTS temp_foo;
CREATE TEMPORARY TABLE IF NOT EXISTS temp_foo AS (
SELECT *
FROM foo
);
SELECT * from temp_foo;
"));
I think it's even possible to simply use selectRaw() but I'm not sure. Also, you can select all rows from temp_foo like this:
DB::table('temp_foo')->get();

You need to look at DB::raw() inside the select(), but also, try using this:
DB::statement('drop table users');

i've done something similar in a migration where i had to create and run a stored procedure. in my up() i used something like this.
public function up() {
$sql = <<<SQL
DROP TABLE IF EXISTS temp_foo;
CREATE TEMPORARY TABLE IF NOT EXISTS temp_foo AS (
SELECT *
FROM foo
);
SELECT * from temp_foo;
SQL;
DB::connection()->getPdo()->exec($sql);
}
you may be able to use
DB::connection()->getPdo()->exec($sql);

Related

How to select content from a table into a new table in SQL stored procedures?

I was trying to write a procedure and needed to copy output_1 table into a new one.
This procedure :
BEGIN
SELECT * INTO newtable FROM output_1;
END
returns the following error :Undeclared variable: newtable
I thought it would create a new table and all its columns automatically.
How do I SELECT multiple columns of a table INTO a new table using a stored procedure?
EDIT :
In stored procedures, when you want to use a table to store data temporarily, you should consider using temporary tables.
Typically, if you try to store a table in a variable, you will get a multiple rows error ; in this case, temporary tables can replace variables.
CREATE TEMPORARY TABLE new_table AS SELECT * FROM output_1;
You cannot select into a table. You possibly intended
create table newtable as select * from output_1;
https://dev.mysql.com/doc/refman/8.0/en/create-table-select.html

mysql temporary table in subquery

I'm trying to use temp table in subquery (stored procedure), but it returns empty result set...
CREATE DEFINER=`root`#`localhost` PROCEDURE `get_profile_with_templates`(IN _username NVARCHAR(50), IN _template NVARCHAR(50))
BEGIN
SELECT id INTO #template FROM profile_template WHERE name=_template LIMIT 1;
SELECT * FROM profile WHERE username=_username AND template=#template LIMIT 1;
CREATE TEMPORARY TABLE IF NOT EXISTS sections SELECT * FROM profile_template_section WHERE template=#template;
**CREATE TEMPORARY TABLE IF NOT EXISTS components SELECT * FROM component_template WHERE section IN (SELECT id FROM sections);**
SELECT * FROM sections;
SELECT * FROM components;
SELECT * FROM component_template_option WHERE component_template IN (SELECT id FROM components);
END
the query between the **'s is the one returns empty...
if I run the same query on the real table, It returns values...
CREATE DEFINER=`root`#`localhost` PROCEDURE `get_profile_with_templates`(IN _username NVARCHAR(50), IN _template NVARCHAR(50))
BEGIN
DROP TEMPORARY TABLE IF EXISTS sections;
DROP TEMPORARY TABLE IF EXISTS components;
SELECT id INTO #template FROM profile_template WHERE name=_template LIMIT 1;
SELECT * FROM profile WHERE username=_username AND template=#template LIMIT 1;
CREATE TEMPORARY TABLE IF NOT EXISTS sections SELECT * FROM profile_template_section WHERE template=#template;
CREATE TEMPORARY TABLE IF NOT EXISTS components SELECT * FROM component_template WHERE section IN (SELECT id FROM sections);
SELECT * FROM sections;
SELECT * FROM components;
SELECT * FROM component_template_option WHERE component_template IN (SELECT id FROM components);
DROP TEMPORARY TABLE IF EXISTS sections;
DROP TEMPORARY TABLE IF EXISTS components;
END
When using CREATE ... SELECT statements, the SELECT portion will not populate the table if it already exists.
If creating temporary tables in a stored procedure that will not be used outside of the procedure, it is best to use DROP TEMPORARY TABLE IF EXISTS statements at the start and end of the procedure. The ending ones are so the procedure cleans up after itself; the starting ones ensure temporary tables left over from previous executions (that errored/failed before dropping them) do not interfere with current executions. You could also wrap the main body of the procedure in a TRY, and have the drops outside of the TRY, to ensure the drops occur, but that is a bit more advanced.
When using session/user/# variables, keep in mind they are global for the database connection and can carry over values; when possible use locally DECLAREd variables (whose scope does not go beyond the procedure). Bonus: Also, try to make sure the names of such variables, and procedure parameters, are not ambiguous with field names of the tables used in the procedure; it can cause very hard to diagnose issues.

MySql - Create a table and select from it in the same procedure

I’m trying to execute this simple code as a procedure in MySql using the PHPMyAdmin
CREATE TEMPORARY TABLE IF NOT EXISTS jobs AS (SELECT
*
FROM
all_jobs
WHERE
job_object_type LIKE 'jobName'
OR
job_object_type LIKE 'jobStatus');
SELECT
*
FROM
jobs
But I’m getting an error (#1064) because of my second SELECT query. I’m coming from MS-SQL and there the SELECT would be executed without any problems. How can I execute the CREATE TABLE X query and direct after that the SELECT * FROM X query in the same procedure?
EDIT: forgot to mention that I’m using the MariaDB
Well that is how it's done using the PHPMyAdmin:
BEGIN
CREATE TEMPORARY TABLE IF NOT EXISTS jobs AS (SELECT
*
FROM
all_jobs
WHERE
job_object_type LIKE 'jobName'
OR
job_object_type LIKE 'jobStatus');
SELECT
*
FROM
jobs;
END
Now everything is being executed as it should be.

Can we create a table in MySQL from scratch using INTO without defining using CREATE before?

I have the following SQL construct:
What I tried todo is to extract data from RBP table and
straight-away creating it into a new_table
INSERT INTO new_table SELECT pdb_id, chain_id FROM RBP
WHERE exp = "X-ray" AND
header = "RNA BINDING PROTEIN/RNA"
But what I got is this:
_mysql_exceptions.ProgrammingError: (1146, "Table 'MYDB.new_table' doesn't exist")
Is it possible to do that without performing this before?
CREATE TABLE new_table (
pdb_id char(8)
chain_id char(2)
)
You can create a virtual table (view) from the existed table as follows:
CREATE VIEW view_name as SELECT column_name from table_name where ;
In your case, you can write
CREATE VIEW view_name as SELECT pdb_id, chain_id from RBP
WHERE exp = "X-ray" AND header = "RNA BINDING PROTEIN/RNA";
MySQL does not create tables when using INSERT INTO ... SELECT * syntax but you can use CREATE TABLE ... SELECT ... as described in http://dev.mysql.com/doc/refman/5.0/en/create-table.html

MySql - Create Table If Not Exists Else Truncate?

Here is the updated question:
the current query is doing something like:
$sql1 = "TRUNCATE TABLE fubar";
$sql2 = "CREATE TEMPORARY TABLE IF NOT EXISTS fubar SELECT id, name FROM barfu";
The first time the method containing this is run, it generates an error message on the truncate since the table doesn't exist yet.
Is my only option to do the CREATE TABLE, run the TRUNCATE TABLE, and then fill the table? (3 separate queries)
original question was:
I've been having a hard time trying to figure out if the following is possible in MySql without having to write block sql:
CREATE TABLE fubar IF NOT EXISTS ELSE TRUNCATE TABLE fubar
If I run truncate separately before the create table, and the table doesn't exist, then I get an error message. I'm trying to eliminate that error message without having to add any more queries.
This code will be executed using PHP.
shmuel613, it would be better to update your original question rather than replying. It's best if there's a single place containing the complete question rather than having it spread out in a discussion.
Ben's answer is reasonable, except he seems to have a 'not' where he doesn't want one. Dropping the table only if it doesn't exist isn't quite right.
You will indeed need multiple statements. Either conditionally create then populate:
CREATE TEMPORARY TABLE IF NOT EXISTS fubar ( id int, name varchar(80) )
TRUNCATE TABLE fubar
INSERT INTO fubar SELECT * FROM barfu
or just drop and recreate
DROP TABLE IF EXISTS fubar
CREATE TEMPORARY TABLE fubar SELECT id, name FROM barfu
With pure SQL those are your two real classes of solutions. I like the second better.
(With a stored procedure you could reduce it to a single statement. Something like: TruncateAndPopulate(fubar) But by the time you write the code for TruncateAndPopulate() you'll spend more time than just using the SQL above.)
You could do the truncate after the 'create if not exists'.
That way it will always exist... and always be empty at that point.
CREATE TABLE fubar IF NOT EXISTS
TRUNCATE TABLE fubar
execute any query if table exists.
Usage: call Edit_table(database-name,table-name,query-string);
Procedure will check for existence of table-name under database-name and will execute query-string if it exists.
Following is the stored procedure:
DELIMITER $$
DROP PROCEDURE IF EXISTS `Edit_table` $$
CREATE PROCEDURE `Edit_table` (in_db_nm varchar(20), in_tbl_nm varchar(20), in_your_query varchar(200))
DETERMINISTIC
BEGIN
DECLARE var_table_count INT;
select count(*) INTO #var_table_count from information_schema.TABLES where TABLE_NAME=in_tbl_nm and TABLE_SCHEMA=in_db_nm;
IF (#var_table_count > 0) THEN
SET #in_your_query = in_your_query;
#SELECT #in_your_query;
PREPARE my_query FROM #in_your_query;
EXECUTE my_query;
ELSE
select "Table Not Found";
END IF;
END $$
DELIMITER ;
More on Mysql
how about:
DROP TABLE IF EXISTS fubar;
CREATE TABLE fubar;
Or did you mean you just want to do it with a single query?
OK then, not bad. To be more specific, the current query is doing something like:
$sql1 = "TRUNCATE TABLE fubar";
$sql2 = "CREATE TEMPORARY TABLE IF NOT EXISTS fubar SELECT id, name FROM barfu";
The first time the method containing this is run, it generates an error message on the truncate since the table doesn't exist yet.
Is my only option to do the "CREATE TABLE", run the "TRUNCATE TABLE", and then fill the table? (3 separate queries)
PS - thanks for responding so quickly!
If you're using PHP, use mysql_list_tables to check that the table exists before TRUNCATE it.