Alternatives for insert ignore into for SQL server - php

i just switched over from a Mysql server to SQL server. But i just found out that INSERT INGORE INTO doesn't work with sql server.
Original code:
INSERT IGNORE INTO DATA_EXACT_INVENTORY_LOCATIONS (ID, Code, Opslaglocatie, Omschrijving, OpVoorraad)
VALUES ('$inventorylocationID','$inventorylocationsItemCode','$inventoryStorageLocationsCode','$inventorylocationsItemDescription','$inventorylocationsCurrenctStock')
I found out that i can use on duplicate key update, but the problem is that i have sql query's with upto 50 variables. So to use on duplicate key update would be alot of work. So what i was wondering is there a better alternative for INSERT IGNORE INTO that's is just plug and play so i don't have to write all variables again.

You can use not exists:
INSERT DATA_EXACT_INVENTORY_LOCATIONS (ID, Code, Opslaglocatie, Omschrijving, OpVoorraad)
SELECT ID, Code, Opslaglocatie, Omschrijving, OpVoorraad
FROM (VALUES ('$inventorylocationID', '$inventorylocationsItemCode', '$inventoryStorageLocationsCode', '$inventorylocationsItemDescription', '$inventorylocationsCurrenctStock')
) V(ID, Code, Opslaglocatie, Omschrijving, OpVoorraad)
WHERE NOT EXISTS (SELECT 1
FROM DATA_EXACT_INVENTORY_LOCATIONS deil
WHERE deil.id = v.id -- or whatever column gets the duplicate key
);
Alternatively, you could rewrite the code to use MERGE. The SELECT should work in both databases.
Let me also add that you should learn to use parameters. Munging query strings with constant values exposes your code to SQL injection attacks and to hard-to-debug syntax errors.

Related

Update SQL row if exists, create if does not exist (in PHP)

I am trying to update a value for a user without knowing if the user exists or not.
Basically: If the user does not exist, create it, and update the value. If it does exist, update the value.
Am I using ON DUPLICATE properly? Can I use WHERE while using ON DUPLICATE?
$sql = "INSERT INTO Users ('$column_name[$i]') VALUES ('$value[$i]') ON DUPLICATE KEY UPDATE '$column_name[$i]'='$value[$i]' WHERE LoginName = '$login_name'";
The error I am getting with this line is:
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 ''record_id') VALUES ('5287469') ON DUPLICATE KEY UPDATE 'record_id' at line 1
Any suggestions on how I should form my query?
The WHERE clause cannot be used with an INSERT ... VALUES statement.
It doesn't matter that there's an ON DUPLICATE KEY clause or not.
MySQL Reference Manual reveals (in a cryptic way) that there is no WHERE clause in an INSERT ... VALUES statement:
https://dev.mysql.com/doc/refman/5.7/en/insert.html
(An INSERT ... SELECT statement can include a WHERE clause, in the SELECT part of the statement, like a normal SELECT statement.)
Don't use single quotes around identifiers (e.g. column names).
If those need to be escaped, use single backtick characters.
Including potentially unsafe values in SQL text throws wide open a whole slew of nasty vulnerabilities, categorized as SQL Injection.
https://www.owasp.org/index.php/SQL_Injection
It could be the values being included in the SQL text have been properly sanitized, or whitelisted. But we're not seeing that in the code, so alarm bells are ringing.
Normative pattern (of just the SQL) would be something like this:
INSERT INTO Users
( `primary_or_unique_key_column`
, `some_column_name`
) VALUES
( 'safe_unique_key_value'
, 'safe_column_value'
)
ON DUPLICATE KEY
UPDATE `some_column_name` = VALUES(`some_column_name`)
If LoginName is the PRIMARY or UNIQUE KEY in the table
INSERT INTO Users
( `loginname`
, `record_id`
) VALUES
( 'safe_loginname_value'
, 'safe_record_id_value'
)
ON DUPLICATE KEY
UPDATE `record_id` = VALUES(`record_id`)
Note that usage of backticks around the column names, and single quotes around literal string values.
Also note the usage of the VALUES function, to reference the value that would have been inserted into the column, if the INSERT had been successful. (Avoids us having to provide the same value twice.
Using prepared statements with bind placeholders, we would need to properly validate the column name that's being incorporated into the SQL text (to avoid SQL Injection vulnerabilities... but the values can be passed in via placeholders.
The SQL text would look like this:
INSERT INTO Users
( `loginname`
, `record_id`
) VALUES
( ?
, ?
)
ON DUPLICATE KEY
UPDATE `record_id` = VALUES(`record_id`)
And code (assuming PDO) would be of the form:
$sth=$dbh->prepare($sql_text);
# check return from prepare
$sth->bindValue(1, $loginname_val, PDO::PARAM_STR);
$sth->bindValue(2, $record_id_val, PDO::PARAM_INT);
$sth->execute();
# check return from execute

SQL Update a whole table with new data

I am running a query every 15 minutes to retrieve new data from an API and store this data in my database.
So every 15 minutes I would like to store the new data in the table and get rid of the all old data in that table.
I am currently using the following method:
$sql = "DELETE FROM self_user_follower
INSERT INTO self_user_follower (username, profile_picture, full_name, user_id, last_updated)
VALUES (:query_username, :query_profile_picture, :query_full_name, :query_user_id, :query_last_updated)";
But it gives me the following error:
Array
(
[0] => 42000
[1] => 1064
[2] => 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 'INSERT INTO self_user_follower (username, profile_picture, full_name, user_id, l' at line 2
)
query_error
Is this the best way to do it or is there a nicer and cleaner way to do this?
If you want to put two SQL queries into one statement string, you have to
separate them with a semi-colon (;)
use the function mysqli_multi_query which supports multiple queries.
Unless you have a very good reason, modify your code so that it executes each query separately. MySQLi offers transaction support if you need that.*
The reason why you need a separate function is instructive; as mentioned in the docs:
An extra API call is used for multiple statements to reduce the likeliness of accidental SQL injection attacks. An attacker may try to add statements such as ; DROP DATABASE mysql or ; SELECT SLEEP(999). If the attacker succeeds in adding SQL to the statement string but mysqli_multi_query is not used, the server will not execute the second, injected and malicious SQL statement.
*: Actually, I'm not even sure the multi_query will execute both queries in the same transaction - I'm just guessing for your reason to use a multi-query.
Multiple statements should be terminated by semi colon
Try this
$sql = "DELETE FROM self_user_follower;
INSERT INTO self_user_follower
(username, profile_picture, full_name, user_id, last_updated)
VALUES (:query_username, :query_profile_picture, :query_full_name, :query_user_id,
:query_last_updated)";

i need to insert values into two different table with single query

How do I join these two queries and execute them as a single query to insert values in two tables:
$sql = mysql_real_escape_string('INSERT INTO admin_export(datetime, product_name, item_code,quantity,subject,export_no) VALUES').implode(',', $row_data);
$sql2 = "insert into `itflower_exportno` (admin_exportno) values('$exportno1')";
You need to separate your two INSERT statements with a semicolon into the single variable.
This(mysql_*) extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQL extension should be used. Switching to PreparedStatements is even more better to ward off SQL Injection attacks !
You can however use transactions as following example.
BEGIN;
INSERT INTO users (username, password)
VALUES('test', 'test');
INSERT INTO profiles (userid, bio, homepage)
VALUES(LAST_INSERT_ID(),'Hello world!', 'http://www.stackoverflow.com');
COMMIT;
What you have in the code are two different inserts.
MySQL doesn't allow for multiple inserts to be run in the same query so you will have to do one first and then the other.
However you can insert multiple rows in the same table in just one query, basically you are restricted to do all the insert you want in one table at a time.
You can't do this.
If you want to do it because you are afraid of the integrity of the data, use transaction .
Second, use suitable transaction isolation level, to ensure that data are reading correctly.

how to insert data from primary key column to foregin key

i am inserting data from a form i want when i will insert data so the first column primary id which is using in second column as a foreign key should be increased
i have tried this code but not working
first table code
$this->db->query("insert into af_ads (ad_title,ad_pic,ad_description)
values ('$title','$filepath','$description')");
second table code
$this->db->query("insert into af_category (cat_type,ad_id_fk)
values ('$category','ad_id')");
NOTE: i want to insert ad_id into ad_id_fk
Try this:
// Your first query
$this->db->query("insert into af_ads(ad_id, ad_title, ad_pic, ad_description)
values ('', '$title', '$filepath', '$description')");
$ad_id = $this->db->insert_id(); // This returns the id that is automatically assigned to that record
// Use the id as foreign key in your second insert query
$this->db->query("insert into af_category (cat_type,ad_id_fk)
values ('$category', $ad_id)");
MySQL provides the LAST_INSERT_ID function as way to retrieve the value generated for an AUTO_INCREMENT column from the immediately preceding INSERT statement.
A lot of client libraries make this conveniently avaiable (e.g. PDO lastInsertId function.)
(I'm not familiar with CodeIgniter or ActiveRecord, so I can't speak to how that's made available.
Your code looks like it's using the PDO interface... but I'm not sure about that.
# either we need to check return from functions for errors
# or we can have PDO do the checks and throw an exception
$this->db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
# attempt insert which will generate AUTO_INCREMENT value
$this->db->query("INSERT (ad_id, ... ) VALUES (NULL, ...)");
# if previous insert successfully inserted a row (or rows)
$ad_id = $this->db->lastInsertId();
You really need to check whether the previous insert was successful or not. If you aren't going to code that check yourself, then PDO does provide a mechanism that performs this checking automatically, and will throw an exception if a MySQL error occurs.
I've avoided copying your original code, which looks like it's vulnerable to SQL Injection. If you're using PDO, you can make effective use of prepared statements with bind placeholders, rather than including values in the SQL text.

how to use mysql update query and mysql insert query together?

this the condition: there is a form in html and php haivng around 120 fields its for a website i am making this form on submitting goes to a php page where i first retrive all the values using $_REQUEST[]and then using insert query insert all of them in their specific coloums in the same table in my mysql database. Now i will have to do all the process again for updating these values. Becuase syntax for insert query and update query are quite different .
I dont want to write another 100 lines of code . Is there any way to use the code i wrote inside my insert query to use to update the data.?
Actually in MySQL there is an alternative syntax for insert that is very similar to the syntax for update. You can write
insert customer set customerid=12345, firstname='Fred', lastname='Jones
etc.
Personally I prefer this syntax because it's easy to see what value is going into each field. This is especially true on records with long lists of fields.
On the minus side, it's not standard SQL, so if you ever decide to port your app to a different database engine, all your inserts would have to be rewritten.
Another option I've occasionally used is to write a little function to create your insert and update statements. Then the syntax of your function can be the same, no matter how different the generated code is.
Another alternative, and depending on requirements and keys, you could use:
replace into tbl (<cols>) values (<vals>)
which will insert if not exist, or replace based on keys (insert/update in one query)
or if you are only inserting and don't want to insert twice, you could use:
insert ignore into tbl (<cols>) values (<vals>)
where if the record is already inserted based on keys, it is gracefully ignored
for more info http://dev.mysql.com/doc/refman/5.0/en/replace.html
There is a quite similar syntax for INSERT and UPDATE:
INSERT INTO <table> SET
column1 = value1,
column2 = value2,
...
;
UPDATE <table> SET
column1 = value1,
column2 = value2,
...
WHERE <condition>
;
INSERT INTO yourtable (field1, field2, field3, ...)
VALUES ($field1, $field2, $field3, ...)
ON DUPLICATE KEY UPDATE field1=VALUES(field1), field2=VALUES(field2), etc...
Details on this construct here.

Categories