I've finally gotten my queries ready to insert into code but now I'm getting an error when running the whole query. I believe it has to do with the drop table function. I originally had them inline and then read that I should remove it and add at the beginning of the query like so:
$query = $this->db->query("DROP TABLE IF EXISTS resultx;");
$query = $this->db->query("DROP TABLE IF EXISTS resulty;");
$query = $this->db->query("
CREATE TEMPORARY TABLE resultx AS
select *, CONCAT(Credit,'_',OrderStat) as consol from (..........
I am creating two temp tables and then joining them in the last query. I am not sure how to put that second DROP temp table back into the full query or if that's even the right way to go.
The error that I'm getting is:
A Database Error Occurred
Error Number: 1064
You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for the right syntax to use
near 'CREATE TEMPORARY TABLE resulty AS select packetDeet,Sales,SaleDate, UserID,Lead' at line 15
Query:
CREATE TEMPORARY TABLE resultx AS
select
*,
CONCAT(Credit,'_',OrderStat) as consol
FROM
( select
packetDetailsId, GROUP_CONCAT(Credit) AS Credit,
GROUP_CONCAT(AccountNum) AS AccountNum,
GROUP_CONCAT(OrderStat) AS OrderStat
FROM
( SELECT
pd_extrafields.packetDetailsId,
CASE WHEN
pd_extrafields.ex_title LIKE ('%Credit%')
THEN pd_extrafields.ex_value
ELSE NULL
END as Credit,
CASE WHEN
pd_extrafields.ex_title LIKE ('%Account%')
THEN pd_extrafields.ex_value
ELSE NULL
END as AccountNum,
CASE WHEN
pd_extrafields.ex_title LIKE ('%Existing%')
THEN pd_extrafields.ex_value
ELSE NULL
END as OrderStat
FROM pd_extrafields
) AS myalias
GROUP BY packetDetailsId
)as TempTab;
CREATE TEMPORARY TABLE resulty AS select packetDeet,Sales,SaleDate, .........
Please let me know if this makes sense or I need to update question with more information.
If you are trying to execute both queries in one call to $this->db->query() the problem is probably that your database library does not permit multiple queries.
To see if that is the problem, you should split them up in two separate queries.
Related
I have one table which stores some records as JSON. I'm trying to increment the numeric value of a key from JSON column. Below is the query I'm executing in Laravel using DB facade.
DB::connection()
->select("
SELECT CAST(JSON_EXTRACT(consumed, '$.max_users') AS INT) INTO #tmp
FROM subscriptions
WHERE `id` = '2';
UPDATE subscriptions
SET consumed = JSON_SET(consumed, '$.max_users', #tmp+1)
WHERE `id` = '2';
");
It works perfectly ok in PhpMyAdmin however when attempting to execute it from Laravel it throws an exception, that SQL syntax is incorrect (where is it incorrect?).
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'UPDATE subscriptions SET consumed = JSON_SET(consumed, '$.max_users', ' at line 5 (SQL: SELECT CAST(JSON_EXTRACT(consumed, '$.max_users') AS INT) INTO #tmp FROM subscriptions WHEREid= '2'; UPDATE subscriptions SET consumed = JSON_SET(consumed, '$.max_users', #tmp+1) WHEREid= '2'; )
My suspicion is select() does not allow two different queries to be ran at once. However in this particular case I need them so in order to make use of #tmp variable. I could retrieve the value of first query and pass it to the second one using PHP, but for the sake of argument, how to run two DB selects at once in Laravel? 🤔
You can use a single update query to increment this value:
UPDATE subscriptions
SET consumed = JSON_SET(consumed, '$.max_users', CAST(JSON_EXTRACT(consumed, '$.max_users') AS INT) + 1)
WHERE `id` = '2';
I have a PHP 7.3 project which connects via PDO to a MySQL database or a MSSQL database, depending on being run on Linux or Windows.
I want to insert a new values into a table, if the unique value is not yet in that table. If it is already in the table, I want to update the non-unique values.
I searched a lot of docs and SO posts, also, but I couldn't find a syntax, which does that in one query for both database types.
SQL Server query:
IF (EXISTS (SELECT * FROM failed_logins_ip_address WHERE ip_address = 'xxx'))
BEGIN
UPDATE failed_logins_ip_address
SET attempts_count = attempts_count + 1, attempt_datetime = CURRENT_TIMESTAMP
WHERE ip_address = 'xxx'
END
ELSE
BEGIN
INSERT INTO failed_logins_ip_address (ip_address, attempts_count, attempt_datetime)
VALUES ('xxx', 1, CURRENT_TIMESTAMP)
END
MySQL query:
INSERT INTO failed_logins_ip_address (ip_address, attempts_count, attempt_datetime)
VALUES ('xxx', 1, CURRENT_TIMESTAMP)
ON DUPLICATE KEY
UPDATE attempts_count = attempts_count + 1, attempt_datetime = CURRENT_TIMESTAMP
'ip_addess' column is unique, and the table structure is identical for both MSSQL and MySQL.
Is there a syntax, which can do an IF INSERT ELSE UPDATE in both database types?
Yes, I do (PDO) parameter binding, xxx is just to shorten the code snippet.
Yes, I could use identical syntax if I did it in two queries (first select, then insert or update) but I want to avoid (hopefully) unnecessary queries.
No, I do not want to insert every login attempt so I do not need the update anymore because I do not need this data.
If the REPLACE approach would work: this does not update, it deletes and inserts, which I also do not want.
My current solution: I check in PHP for the current database type and switch/case the query strings. It is clean but one string is even less smelly ;-)
UPDATE:
I changed the MSSQL query around: from of IF NOT EXISTS TO IF EXISTS to improve the efficiency. UPDATE will occur a lot more often than INSERT, so in most of the cases, only the first (sub)query will be executed.
After digging deeper, I found this post by a Derek Dieter, which describes how to replace SQL Server's IF EXISTS ELSE by WHERE EXISTS:
https://sqlserverplanet.com/optimization/avoiding-if-else-by-using-where-exists
The WHERE EXISTS syntax seems to be the same in MySQL and MSSQL.
Derek Dieter's example, with IF EXSISTS:
IF NOT EXISTS (SELECT 1 FROM customer_totals WHERE cust_id = #cust_id)
BEGIN
INSERT INTO customer_totals
(
cust_id,
order_amt
)
SELECT
cust_id = #cust_id
,order_amt = #order_amt
END
ELSE
UPDATE customer
SET order_amt = order_amt + #order_amt
WHERE cust_id = #cust_id
END
Derek Dieter's example, with WHERE EXISTS:
INSERT INTO customer_totals
(
cust_id,
order_amt
)
SELECT TOP 1 — important since we’re not constraining any records
cust_id = #cust_id
,order_amt = #order_amt
FROM customer_totals ct
WHERE NOT EXISTS — this replaces the if statement
(
SELECT 1
FROM customer_totals
WHERE cust_id = #cust_id
)
SET #rowcount = ##ROWCOUNT — return back the rows that got inserted
UPDATE customer
SET order_amt = order_amt + #order_amt
WHERE #rowcount = 0
AND cust_id = #cust_id — if no rows were inserted, the cust_id must exist, so update
I still have to test it, though, in MySQL. I'll update this post and add the code, if it works.
If you are using PHP, then you are calling the code through an interface. You can do the following:
Create a unique index on ip_address.
Attempt to insert a new row. This will fail if the row already exists.
If the insert fails (particularly with a duplicate key error), then update the existing row.
However, your goal of trying to have the same code in both databases is . . . just not going to work very well. The two databases are rather different. Perhaps you should consider constructing stored procedures in each database to do what you want and then calling those stored procedures.
I have two different Databases, names:
dbtest: Table 1
dbtest2: Table 2
I want to select all the data and new entries from dbtest Table 1 to dbtest2 Table 2.
I have tried this
$sqlfin = "INSERT INTO dbtest2.Table2 SELECT * FROM dbtest.Table1";
$resultfi = mysqli_query($db_conn, $sqlfin);
But no luck so far. How can I assure that new Records are insert into both table ? Any help would be appreciated?
lets try it in this format
INSERT INTO `dbtest2`.`Table2` SELECT * FROM `dbtest`.`Table1`
The following conditions hold for INSERT ... SELECT statements:
Specify IGNORE to ignore rows that would cause duplicate-key violations.
AUTO_INCREMENT columns work as usual.
To ensure that the binary log can be used to re-create the original tables, MySQL does not permit concurrent inserts for INSERT ... SELECT
statements (see Section 8.11.3, “Concurrent Inserts”).
To avoid ambiguous column reference problems when the SELECT and the INSERT refer to the same table, provide a unique alias for each
table used in the SELECT part, and qualify column names in that
part with the appropriate alias.
INSERT ... SELECT Syntax
Create Trigger: for adding new entries
CREATE TRIGGER copy_record BEFORE INSERT ON dbtest.Table1
FOR EACH ROW
BEGIN
INSERT INTO dbtest2.Table2 (first_name, last_name) VALUES (new.first_name, new.last_name);
END
trigger_event indicates the kind of operation that activates the
trigger. These trigger_event values are permitted:
INSERT: The trigger activates whenever a new row is inserted into the table; for example, through INSERT, LOAD DATA, and REPLACE
statements.
UPDATE: The trigger activates whenever a row is modified; for example, through UPDATE statements.
DELETE: The trigger activates whenever a row is deleted from the table; for example, through DELETE and REPLACE statements. DROP TABLE
and TRUNCATE TABLE statements on the table do not activate this
trigger, because they do not use DELETE. Dropping a partition does not
activate DELETE triggers, either.
CREATE TRIGGER Syntax
Try this query for your desired task :
Query First (Create Table exactly same like in old database, if you have not):
CREATE TABLE dbtest2.Table2 LIKE dbtest.Table1;
Query Second (Insert all data to newly created table) :
INSERT INTO dbtest2.Table2 SELECT * FROM dbtest.Table1;
Your query looks correct but will fail if the 2 tables have a different structure. Specify the columns to avoid it like:
INSERT INTO dbtest2.Table2 (2_col_1, 2_col_2) SELECT 1_col_1, 1_col_2 FROM dbtest.Table1
With PDO (kind of alternative answer, I don't know much for Mysqli):
You could connect to Mysql with PDO without giving a database name when working with multiple ones (but this isn't mandatory), like:
$db = new PDO( "mysql:host=" . $host . ";", $user, $password, $options );
Then write the Database names, tables and columns like when making a JOIN (as you did): separated by a .
// an example ..
$useDb = $db->query("INSERT INTO db_1.table1 (value_1, value_2) SELECT value_3, value_4 FROM db_2.table2 WHERE db_2.table2.id = 5");
(example tested and working fine)
INSERT INTO dbtest2 (
id,
name,
status )
SELECT id,
name,
'1'
FROM dbtest
ORDER BY id ASC
You can use INSERT...SELECT syntax. Note that you can quote '1' directly in the SELECT part.
I have table images with ID's starting from 1 to 5000. On the page they are showed straight from 1 to 5000. What I wonder is it possible to scramble the records inside database table not to query them by RAND() on the page because they will be random on every refresh. I don't want this.
For example id(1) to become id(343).. id(453)->id(4444) and so on.. just scrambling them.
UPDATE:
This is the query which I'm trying
alter table images add column randorder double;
update table images
set randorder = rand();
create index idx_table_randorder on table(randorder);
When is executed I got column randorder with NULL but the query return again
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'table images set randorder = rand()' at line 1
How about this?
alter table add column randorder double;
update table
set randorder = rand();
create index idx_table_randorder on table(randorder);
Then you can "shuffle" the records by doing:
select t.*
from table t
order by randorder;
This will use the index so it will be fast. It is stable, so it will work by paging. When you want to change the ordering, you can use the update.
Save the rows into an array. Then run:
shuffle($array);
See http://php.net/manual/en/function.shuffle.php
I have the following query, to copy a row within a table and alter a few columns.
CREATE TEMPORARY TABLE temp_table AS
SELECT *
FROM table1
WHERE offertecode = '1c12a23453453458e492230df420972';
UPDATE temp_table
SET offertecode = '82a24c7da2342423424351804ab043',
id = NULL,
reference = '[COPY] subject';
INSERT INTO table1
SELECT *
FROM temp_table;
DROP TEMPORARY TABLE temp_table;
This works perfectly fine in phpmyadmin, but I cant get it to work from within PHP, I get an error:
You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for the right syntax
to use near 'UPDATE temp_table SET offertecode = '82a24c7da2342423424351804ab043',
id = ' at line 5
Can anyone help me on how to execute this query in PHP?
PHP code:
$mysqli->query("CREATE TEMPORARY TABLE temp_table AS
SELECT *
FROM table1
WHERE offertecode = '1c12a23453453458e492230df420972';
UPDATE temp_table
SET offertecode = '82a24c7da2342423424351804ab043',
id = NULL,
reference = '[COPY] subject';
INSERT INTO table1
SELECT *
FROM temp_table;
DROP TEMPORARY TABLE temp_table;");
Thanks!
This doesn't address the mysqli problem (which is having four statements in a single query). You should run those separately. But, you don't need four statements. Just do:
insert into table1(offertecode, id, reference, <rest of columns>)
select '82a24c7da2342423424351804ab043' as offertecode, NULL as id, '[COPY] subject' as reference,
<rest of columns>
from table1
where offertecode = '1c12a23453453458e492230df420972';
An insert . . . select statement can refer to the same table in both parts. Even in MySQL.
You need to use $mysqli->multi_query. The basic answer is you cannot run multiple queries using $mysqli->query. The syntax error is due to a second query trying to to be run under $mysqli->query which only allows one main query. That query can contain sub or nested queries, but only one main query. To run multiple queries you have to use $mysqli->multi_query