SQL Query functioning when executed in Db Browser for SQLite but not when implemented in node.js - sql

SQL Statement working perfectly fine when ran in DB Browser for SQLite but not in node.js code. Are there any changes that I need to make?
I created a query that would INSERT values into a table if the specified values did not exist, or UPDATE values if they do exist.
When ran in the DB Browser for SQLite, the query worked perfectly but when I tried to implement it in my code, the UPDATE statement works but not the INSERT statement, with no errors being returned. Why is that?
let sql2 = `UPDATE inventory
SET item_name = '${itemChosen}', item_amount = ${amountChosen) where discordId = '${user}';
INSERT INTO inventory (discordId,item_name,item_amount)
select '${user}','${itemChosen}',${amountChosen}
WHERE (Select changes() = 0);`;
db.all(sql2, [], (err, rows) => {
if (err) {
throw (err)
}
message.reply("Item purchased!");
})
The UPDATE statement works fine, but the INSERT statement will never get executed. No error messages are returned.

Related

Tablegateway "insert" gets executed but no values are written into table

Environment: Docker container, where PHPand MySQL runs in seperated containers
I have a table "persons" and want to insert values using TableGateway. The code gets executed and I can catch the last inserted value. It's an autoincrement and every performed insert on this table increments this value.
But no values are saved in the table (e.g. phone)
public function __construct(
...
TableGateway $tablePersons,
...
) {
...
$this->tablePersons = $tablePersons;
...
}
...
$this->tablePersons->insert(['phone' => 123456]);
$id = $this->tablePersons->lastInsertValue;
I printed the sql string out and it looks fine.
$sql = $this->tablePersons->getSql();
$insert = $sql->insert();
$insert->values(['phone' => 123456]);
print $sql->buildSqlString($insert);
// Result: INSERT INTO `persons` (`phone`) VALUES ('123456')
I performed this query on phpmyadmin and everthing looks good, values are stored.
mysql_error.log is empty
mysql.log shows the following:
2019-05-12T23:34:20.940510Z 34 Connect root#172.20.0.5 on app using TCP/IP
2019-05-12T23:34:20.940795Z 34 Query SET AUTOCOMMIT=0
2019-05-12T23:34:20.943878Z 34 Query INSERT INTO `persons` (`phone`) VALUES (42)
2019-05-12T23:34:20.944329Z 34 Quit
To bypass the zend-framework, I went to the index.php and performed a classic mysqli query:
$conn = new mysqli(## same values as in the zend-db adapter config ##);
$sql = "INSERT INTO persons (phone) VALUES (123456)";
$conn->query($sql);
This works perfectly fine - a new row gets stored. So I think, a problem with the environment may be excluded.
I need a hint, an idea why the values are not saved when I run the query with the framework functions.
Try to confirm that you' ve to initiated a database transaction that is preventing AUTO_COMMIT of the inserted values. Also, confirm that the field length for the phone and other fields are large enough to store the values passed.

How do we confirm SQL Data Manipulation Language (DML) statement is success?

I have the following code to confirm the SQL result
int i = stmt.executeUpdate();
if (i > 0) {
System.out.println("success");
} else {
System.out.println("stuck somewhere");
}
JavaDoc says "executeUpdate returns"
either (1) the row count for SQL Data Manipulation Language (DML) statementsor (2) 0 for SQL statements that return nothing
Now, we have done partitioning using TRIGGER and my INSERT query returns 0 for all Insert queries and records are inserted into appropriate partitions.
So, now I have to remove the check for success and rely on SQLEXCEPTION for errors.
Can I ignore the following check and trust the records are Inserted/Updated in DB.
if (i > 0) {
System.out.println("success");
} else {
System.out.println("stuck somewhere");
}

SQL query to update column in a table

I have a code based website in which an employee has to update their reward points by the coupon code provides them and when that code reflect their account means when points are updated in their account they are able to shop in the website. But there is a restriction for the code that code is deleted once used. Sometimes I found a query from customers that they update their account with the code provided but code did not reflect the account and deleted from the database and so thereafter they are not able to use the code again now I want that code only deleted when the code update points in their account. I have an another table named customer_reward where code saved after add points in the customers account but the code that not reflect account recharge is not saved in that table so I want that code only delete when that code is saved in the customer_reward table.
the complete code is given below:
<?php
if(isset($_POST['sub'])){
$db_host="localhost";
$db_username="root";
$db_password="";
$db_name="14";
$con=mysql_connect("$db_host", "$db_username", "$db_password") or die("could not connect to mysql!!!");
if($con=="")
{
echo "Database not connected!!!!";
}
else
{
$isdb=mysql_select_db("$db_name") or die("database not available!!!!");
if($isdb=="")
{
echo "database not selected!!!!";
}
else
{
$emp_ID=$_POST['emp_ID'];
$code=$_POST['code'];
$query = mysql_query("select * from oc_abhireward where `Code`='$code'") or die (mysql_error());
$data=mysql_fetch_assoc($query);
$code_db=$data['Code'];
$points_db=$data['Point'];
if($code==$code_db)
{
$query1 = mysql_query("select * from oc_customer where `emp_ID`='$emp_ID'") or die (mysql_error());
$data1=mysql_fetch_assoc($query1);
$customer_id=$data1['customer_id'];
$query2=mysql_query("INSERT INTO `oc_customer_reward` (customer_id, order_id, description, Code, points, date_added) VALUES ($customer_id, 0, 'rewarded', '$code', $points_db, NOW());");
$query4=mysql_query("INSERT INTO `oc_customer_recharge`(emp_ID, Code, points, date_added) VALUES ('$emp_ID', '$code', $points_db, NOW());");
if ($code==$code_db)
{
query5 = mysql_query("select * from oc_customer_recharge where Code='$code'")or die (mysql_error());
$data2=mysql_fetch_assoc($query4);
$emp_ID=$data2['emp_ID'];
$query6 = mysql_query("DELETE FROM oc_abhireward WHERE Code='$code'");
}
else
{
exit();
}
header("location:http://localhost/14/index.php?route=account/account");
exit();
}
else
{
}
}
}
}
?>
What's the relationship between Employee and Customer?
You are querying oc_customer by emp_ID, and getting customer_id from it. So is oc_customer unique on emp_id? If not, then the customer you end up getting (and so the one you'll apply the reward to) is effectively random. Instead, you need to pass in the customer's customer_id rather than the emp_id.
One other thing; You're using the "$POST"ed values directly in the SQL statements. That opens you up to a SQL-Injection attack. Check out How can I prevent SQL injection in PHP?
The best way possible here could be creating a trigger (for deleting the code) that will fired only when the update of points has been made.
CREATE TRIGGER trigger_name
AFTER INSERT
ON table_name FOR EACH ROW
BEGIN
-- logic for deleting the corresponding CODE
END;
Hope this will bring you closer to what you seek.
Ak
I think the problem is that you are really not veryfing whether a record was inserted in your oc_customer_reward table.
There are multiple ways of solving this problem.
You can modify your delete query to check oc_customer_reward table. This could be something on the lines of:
DELETE Table1
FROM Table1
INNER JOIN Table2 ON Table1.ID = Table2.ID
Create a trigger which will delete data in oc_reward table whenever a record is inserted in oc_customer_reward. You can look up triggers here
CREATE TABLE reward_code_table
(reward_code INT, random_col VARCHAR(50))
;
INSERT INTO reward_code_table
(`reward_code`, `random_col`)
VALUES
(1, 'First code'),
(2, 'Second code'),
(3, 'Third code')
;
CREATE TABLE insert_code_table
(customer_code INT, another_random_col VARCHAR(50))
;
DELIMITER //
CREATE TRIGGER del_after_insert
AFTER INSERT
ON insert_code_table
FOR EACH ROW
BEGIN
DELETE FROM reward_code_table WHERE reward_code = NEW.customer_code;
END;
//
DELIMITER ;
INSERT INTO insert_code_table(customer_code, another_random_col)
VALUES (2, "del 2 from reward table");
After inserting into one table, it deletes record from the other table.
You can checkout a sample SQLFiddle. Note that I have kept the delimiter as // in the fiddle example
Also consider using prepared statements to prevent basic mysql injections.

UPSERT in SQLite

I don't want to use REPLACE INTO because it's basically a DELETE and INSERT and it's complicated to use the data from the old columns.
INSERT OR IGNORE is a bit of a hack because all errors are ignored, so this is not an option.
I've read a blog article which uses the following:
UPDATE Table1 SET (...) WHERE Column1='SomeValue'
IF ##ROWCOUNT=0
INSERT INTO Table1 VALUES (...)
I like this approach really much, but I don't know how I can implement this IF-clause with the ##ROWCOUNT in SQLite, this is what I got:
SELECT CASE (SELECT
CASE
WHEN EXISTS(SELECT 1 FROM t WHERE id=2)
THEN 1
ELSE 0
END)
WHEN 1
UPDATE t set a='pdf' WHERE id=2;
ELSE
INSERT INTO t (a) VALUES ('pdf');
END
the SELECT CASE seems to be the only way to use a CASE-clause in SQLite because everything else throws an syntax error. But it's also not possible to use a UPDATE- or INSERT-statement in the SELECT CASE, so this throws an error.
I've tried the following
UPDATE t set a='pdf' WHERE id=2;
CASE WHEN (changes()=0) THEN
INSERT INTO t (a) VALUES ('pdf');
END
but this doesn't work, because the CASE-clause throws an syntax error.
can someone provide an example using ##ROWCOUNT for an UPSERT in SQLite?
SQLite has no built-in UPSERT-like statement that doesn't delete the old record.
You should check the number of changes in your program, and execute the INSERT conditionally.
However, if you really want to do this in SQL, it's possible; but you have to use the INSERT ... SELECT ... form so that you are able to insert zero records, if needed:
BEGIN;
UPDATE t SET a = 'pdf' WHERE id = 2;
INSERT INTO t(id, a) SELECT 2, 'pdf' WHERE changes() = 0;
COMMIT;
You should use sqlite API in this case and write "IF logic" in your application.
sqlite3_prepare16_v2(stmt1, "UPDATE t SET a=? WHERE id=?");
sqlite3_prepare16_v2(stmt2, "INSERT INTO t(id, a) VALUES(?, ?)");
for(...) // iterate by rows to be updated/inserted
{
//set parameter values for stmt1
sqlite3_step(stmt1);
if( !sqlite3_changes(dbh) )
{
//set parameter values for stmt2
sqlite3_step(stmt2);
}
}

Two simple MySQL statements causing syntax error

I'm confounded. The following MySQL query:
SET #a := 0;
SELECT *
FROM users;
Gives the error:
Invalid query: 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 'SELECT * FROM users' at line 2`
When I switch the order of the statements, I get the same error, again on line 2 (even though I switched them)
However, either line by themselves runs fine. What could possibly cause this?
I bet you're trying to perform this query in the mysql_query() (or some similar function from any programming language), but it accepts only single query. So the solution is to split this queries into 2 calls.
you can do it in one query as follows:
The trick
select #a:=#a+1, u.*
from
users u
join (select #a:=0) a
or be adventerous and use a stored procedure so it's always a single call :P
Stored procedure
drop procedure if exists list_users;
delimiter #
create procedure list_users()
begin
set #a = 0;
select #a:=#a+1, u.* from users u;
end #
delimiter ;
call list_users();
PHP script
$conn = new mysqli("localhost", "foo_dbo", "pass", "foo_db", 3306);
$result = $conn->query("call list_users()");
while($row = $result->fetch_assoc()){
...
}
$result->close();
$conn->close();