Im trying to execute something like this
$SQL = "INSERT into cb_sent_alerts(user_id,message)
Select id, ' :message ' from story1";
$stmt->bindValue(':message', $_POST['message']);
But that just sends :message to the database, not the values of $_POST['message']; What can i do?
EDIT: very sorry should have specified, :message is not a column in cb_sent_alerts, rather i want the message there as a string.
Though it's never mentioned in the doc explicitly, you can work with placeholders in SELECT part of INSERT ... SELECT query the same way as with any other type of query. So this:
INSERT INTO cb_sent_alerts(user_id,message)
SELECT id, :message FROM story1
... end up with the right value (a string) if bound up by bindValue(':message', $_POST('message') call.
Note that placeholders cannot be used for the column and table names, so the thing you were afraid of is just not possible. )
Related
I am having with my query because Insert into value and select is not working, Is this the proper way of using it? thankyou!
This is my query line
$sql = "INSERT INTO `stud_class` (`stud_fullname`, `stud_uid`,`stud_code`, `stud_subject`, `stud_cname`,`stat`) VALUES ('$stud_full','$stud_uid',(SELECT subject_code,subsubject,class_Name FROM subject WHERE subject_code = '$subcode'),1)";
A subquery that's used as an expression is only allowed to return one value, not multiple columns.
You need to use the SELECT query as the source of all the values, not as an expression inside the VALUES list.
$sql = "INSERT INTO `stud_class` (`stud_fullname`, `stud_uid`,`stud_code`, `stud_subject`, `stud_cname`,`stat`)
SELECT '$stud_full','$stud_uid', subject_code,subsubject,class_Name, 1
FROM subject WHERE subject_code = '$subcode')";
You should also use a prepared statement rather than substituting variables into the SQL string. See How can I prevent SQL injection in PHP?
Getting really confused surrounding this INSERT INTO. It should insert three fields into the table, userID, activateKey and isActivated.
The activateKey is a 25 letter randomly generated key such as 63n20kw24ba1mlox34e8n2awv
The userID comes from another table and is set by auto_increment.
The isActivated is always 0 at this stage.
It seems like quite a simple INSERT statement
if (!mysqli_query($con,"INSERT INTO activations (userID,activationKey,isActivated) VALUES (".$userID.",".$activateKey.",'0')"))
{
echo("Error description: " . mysqli_error($con));
}
However it doesn't work when I include the $activateKey field. What it does is try to search the string variable $activateKey as a column name. The error I get is:
Error description: Unknown column '63n20kw24ba1mlox34e8n2awv' in 'field list'
Of course there is no such column as 63n20kw24ba1mlox34e8n2awv, this is the data I'm trying to insert, hence why it's in the VALUES section. Any ideas why it's trying to search this as the column name?
Edit to clarify: the var is activateKey, the column name is activationKey
I would put the query in a different variable to avoid confusion, and PHP automatically substitutes variable names in strings in double quotes.
Try this:
<?php
$query = "INSERT INTO activations (userID,activationKey,isActivated) VALUES($userID,'$activateKey','0')
if (!mysqli_query($con,$query)
{
echo("Error description: " . mysqli_error($con));
}
You are not surrounding the values with quotes, that's why they get interpreted as variable names.
Use single quotes, like this:
"INSERT INTO activations (userID,activationKey,isActivated) VALUES
('".$userID."','".$activateKey."','0')"
However, be aware that stringing together query strings exposes you to SQL injection attacks, if that's a concern in your code you should use parameterized queries. In fact, using parameterized queries is always better.
Change your query to this:
"INSERT INTO activations
(userID,activationKey,isActivated)
VALUES ('$userID','$activateKey','0')"
You dont need to use the concatenation (.) operator as variables will be interpolated into the string.
The single quotes tell mysql to treat the variables as literals instead of column names.
As a side note you would be better to use parameterized queries. See How can I prevent SQL injection in PHP?
Solved!
It was a case of not properly wrapping the dynamic fields (the vars in the VALUES section) in ticks:
if (!mysqli_query($con,"INSERT INTO activations (userID,activationKey,isActivated) VALUES ('".$userID."','".$activateKey."','0')"))
Instead of
if (!mysqli_query($con,"INSERT INTO activations (userID,activationKey,isActivated) VALUES (".$userID.",".$activateKey.",'0')"))
Might be a difficult one to spot. The variables still need to be 'in ticks' or they won't register as strings.
As activationKey is a string column, you must use single quotes for $activationKey.
Try with:
if (!mysqli_query($con,"INSERT INTO activations (userID,activationKey,isActivated)
VALUES (".$userID.",'".$activateKey."','0')"))
So, I'm working on some PHP and using prepared statements to access my database with mysqli, the following statement has a different outcome when prepared statements are used than if I
run the query using HeidiSQL, manually inserting the values
run the query without using prepared statements and manually entering the values
Prepared statement query:
$qStr = "SELECT id, head, descrip, img.dir
FROM CS_P, img,Q_Q_Items
WHERE CS_P.id = Q_Q_Items.I_ID
AND CS_P.id = img.Product_ID
AND img.priority=1
AND CS_P.id NOT IN(
SELECT ID2
FROM I_Cols, Q_Q_Items
WHERE ID2 = Q_Q_Items.I_ID
AND Q_Q_Items.Q_ID = ?
AND ID1 IN (".$madeMarks.")
)
AND Q_Q_Items.Q_ID = ?;";
Manually entered query:
SELECT id, head, descrip, img.dir
FROM CS_P, img,Q_Q_Items
WHERE CS_P.id = Q_Q_Items.I_ID
AND CS_P.id = img.Product_ID
AND img.priority=1
AND CS_P.id NOT IN(
SELECT ID2
FROM I_Cols, Q_Q_Items
WHERE ID2 = Q_Q_Items.I_ID
AND Q_Q_Items.Q_ID = 2
AND ID1 IN (35)
)
AND Q_Q_Items.Q_ID = 2;
The difference:
This statement is intended to omit rows where the value of ID_Cols.ID1 matches one of the values to be bound in place of $madeMarks. $mademarks is just a string of question marks that are inserted into the string so that I can insert numeric values that are posted to the PHP using AJAX and correspond to choices the user has previously made.
When I run this query on the SQL server directly it correctly omits rows where ID1 is in the values entered in place of $madeMarks in the prepared statement, with prepared statements these rows are always included and they shouldn't be as this means a previous choice made by the user clashes with this choice meaning it should not be displayed.
Is the way prepared statements are processed making this query impossible to be executed as intended?
Further information:
I have echoed out the values and they are correct integers, no strings or characters and all of the data is correct before it is bound to the prepared statement, I have used intval to make sure of this.
JSON encoded array of values bound to the query:
[2,35,2]
Bind type string:
'iii'
$madeMarks:
'?'
I have bound the values to the statement with 'i' binds as the database is expecting.
ID1 and ID2 are integers.
//////////////////////////////////////////////////////////////////////
It is now functional.
This isn't really an answer but is is a workaround, I just used preg_replace to replace any non-numeric chars with empty characters and then built the in statement with a for loop, inserting values from the choices array into the statement. There is no vulnerability to SQL injection as it is only numeric characters, this would be vulnerable to injection if it was a string that I had to compare.
Do not do this, it is hackish and bad, just use PDO.
I spent few hours trying to insert a query using PDO, and finally I realized that I can`t do it (dont know how).
The problem is in fact that column name have "?" in it. One of columns is named "If HSM Visa to what year?". Because of that, Every time I do insert I get either:
- wrong number of parameters passed or
- cant mix name and ? in query.
I gave up from this, and I'm going to alter mysql table I got to work with (who is naming columns with question marks anyway ?), but I'm still curious.
INSERT INTO `tbl_maindetails` (`Id`,`Title`,`If HSM Visa to what year?`) VALUES (?, ?, ?)
Thanks,
Goran
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
will solve the issue, I believe.
I have the same problem! I tried to get around the confusion between the character "?" in the column (field) names and the same character "?" as a positional (un-named) placeholder in PDO, by switching to NAMED parameter binding... but the problem STILL persists :(
Now, PDO sees the "?" in the column names and thinks I'm mixing up named and positional parameters!
For example:
UPDATE myTable SET `title` = :title, `Underwater?` = :Underwater
WHERE ID='123'
together with the following binding:
Array ( [:title] => test [:Underwater] => 0)
produces thee following ERROR MESSAGE:
"SQLSTATE[HY093]: Invalid parameter number: mixed named and positional parameters"
Notice that I avoided placing any "?" inside the placeholder itself (it's ":Underwater" rather than ":Underwater?", but it was no help...)
Clearly, this is a bug! PDO is seeing the "?" in the column names, and jumping to the conclusion that it's a positional placeholder, even if we are strictly using NAME parameter binding!
I'll see if I can report this bug...
Since MySQL allows question marks in the column names, I see no compelling reason why we must avoid them! (Though, in the short term, I'll do that, sigh...)
Here is the only (ugly) solution that I could come up with:
$db->query("SET #column_name = 'question?'");
$db->query("SET #sql_text = CONCAT('INSERT INTO table1 SET `', #column_name, '` = ?')");
$db->query("PREPARE stmt FROM #sql_text;");
$db->query("SET #v = ?", 'something');
$db->query("EXECUTE stmt USING #v");
echo $db->insert_id();
This will insert a new row into table1 with question? = 'something'
This code is using a PDO wrapper so you'll need to adjust for that.
In the long run I think you made the right choice by renaming the column.
I've user profile update page and have some forms to update, here they are
NAME
SURNAME
password
phone
And I am trying to make this update without big script, I mean I don't want to define if for example NAME exists or not and so on. I want that if any marked form value exists it changed in mysql. How I know this is possible with mysqli_prepare statement. I've written sql like this
$stmt = "UPDATE table SET NAME=?,SURNAME=?,PASSWORD=?,PHONE=? WHERE email='" . $email . "'";
but something wrong, any ideas how to do it ? And also please advice why it is better way to use mysqli_prepare , why it is safe too ?
PS. I do not write php script because I've not any problem with it
UPDATE
I've marked sql statement and above this script in php I am writting this =>
if (isset($_POST['name']){
$name = $_POST['name'];
} else {
$name = null;
}
and so on ...
but it doesn't execute , nothing error msg is shown up , because I think something wrong with sql statement
Just want if some of detail is filled it updated and if all fields are filled all updated, how to write with script?
I can not understand this question marks in sql statement , does it means that if for example NAME is not exists it is ignored ?
The question marks in your SQL string not part of the SQL syntax, they are placeholders for the actual parameters. If you want to do it like this, you should first make a SQL statement, and then set the parameters.
Something like
$con = new mysqli($hostname,$username,$password,$database);
$statement = $con->prepare( "UPDATE table SET NAME=?,SURNAME=?,".
"`PASSWORD`=?,PHONE=? ".
" WHERE email=?");
$statement->bind_param("sssss",$name,$surname,$pass,$phone,$email);
example derived of http://www.xphp.info/security/getting-started-with-mysqli/
Also note the comment of ThiefMaster: password is a reserved word in MySQL so you will need to put it in backticks (``)
Alternatively you directly insert the values into the mysql string, like you initially did with the email address. You need to escape the values in that case, by using mysql_real_escape_string()
Note that you are in both cases replacing ALL values with what was set, be it NULL or a string, or whatever.