Mulitple values in PHP Prepared Statements - php

Using prepared statements, I've got 23 values that are going to be entered (see below). Does this mean I need to type out 23 ? placements or is there some kind of default / shorthand?
INSERT INTO table
(
job_id, property_title, property_location, property_price, number_of_bedrooms,
number_of_receptions, number_of_bathrooms, epc, train_station_miles,
garden_acres, garage, off_road_parking, main_photo,
photo_1, photo_2, return_email, office,
additional_information, timestamp_added, added_by_user_id, timestamp_updated,
updated_by_user_id, status_id
)
VALUES (?, ?, ?, ?,......etc x 23)
I've never thought about this before as I've only used a smaller number of values but 23 seems a bit excessive if there is some kind of shorthand

This should be suitable for you, to shorthand binding all of your inputs into the query I'd recommend this code:
$placeholders = implode(', ', array_fill(0, 23, '?'));
$stmt = $connection->prepare("INSERT INTO table
(
... rest of the statement....
)
VALUES ($placeholders)");

Related

Failed to get data from localhost using php in android

Im new at Android. I'm trying to fetch some data from localhost server. My query is running perfectly on phpMyAdmin But I facing error in api. I have very little knowledge about Php so did not get what the issue is.
Code:
public function saveUserProgress($user_id,$course_id,$topic_id,$quiz_marks){
$output = $this->con->prepare("INSERT INTO user_progress (user_id, course_id, topic_id,quiz_marks)
VALUES (?, ?, ?,?)
ON DUPLICATE KEY UPDATE
user_id=?, course_id=?, topic_id=?, quiz_marks = quiz_marks + ?");
$output->bind_param("iiii",$user_id,$course_id,$topic_id,$quiz_marks);
if($output->execute()){
return PROGRESS_SAVED;
}else{
return ERROR_OCCUR;
}
}
Error:
{"error":true,"message":403}
Warning: mysqli_stmt::bind_param(): Number of variables doesn't match number of parameters in prepared statement
If as you said your unique key is user_id and course_id then you do not need to update them on duplicate key. You only need to update the remaining 2 values. Together with the 4 you wanted to add it makes 6 placeholders, so you need to bind 6 variables.
$output = $this->con->prepare("INSERT INTO user_progress (user_id, course_id, topic_id,quiz_marks)
VALUES (?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
topic_id=?, quiz_marks = quiz_marks + ?");
$output->bind_param("iiiiii", $user_id, $course_id, $topic_id, $quiz_marks, $topic_id, $quiz_marks);

php mysqli repeated fields in prepared statement

I need to convert an existing project from mysql to mysqli and using prepared statement.
In the existing project there are queries that uses repeated variable values.
One such example is this: where the $prev_yr is used 3 times.
$sqlins = "Insert into studentclass (`StudentID`, `ClassID`, `Year`, `Level`, `SNo`, `TermList`, `DateStart`, `DateEnd`)
select StudentID, '$prev_cl', '$prev_yr', '$prev_lvl', '', '123456789', '$prev_yr-01-01', '$prev_yr-12-31' from student Where StudentID in ($ids) ";
Is there a better method than this:
$sqlins = "Insert into studentclass (`StudentID`, `ClassID`, `Year`, `Level`, `SNo`, `TermList`, `DateStart`, `DateEnd`)
select StudentID, '?', '?', '?', '', '123456789', '?-01-01', '?-12-31' from student Where StudentID in (?) ";
$stmt = $mysqli->prepare($sqlins);
$stmt->bind_param("ssssss", $prev_cl,$prev_yr,$prev_lvl,$prev_yr,$prev_yr,$ids);
$stmt->execute();
I am wondering if there is a way of binding the $prev_yr once for all 3 occurrences.
Because there are other queries that may have 2 occurrences of $prev_lvl, 5 occurrences of $prev_yr etc in one statement. The idea is that when the repeated occurrences of multiple variables becomes many in a statement - it becomes quite confusing to arrange them in the bind_param.
Any solution?
Thank you.
Does it even work like that, typical you wont't do this '?-01-01' in a query. I haven't used Mysqli, in about 4 years, as all I use now a days is PDO. But as far as I know when you send that to prepare it's gonna puke on the ? being in a string.
I would split it, there actually is no real need to do the select because the only thing being selected is the studentID which you already have. Simply
$insert = $mysqli->prepare("Insert into studentclass (`StudentID`, `ClassID`, `Year`, `Level`, `SNo`, `TermList`, `DateStart`, `DateEnd`)VALUES(?, ?, ?, ?, ?, ?, ?, ?)");
foreach( $ids AS $id ){
$stmt->bind_param("issssiss", $id, $prev_cl,$prev_yr,$prev_lvl,'', '123456789', $prev_yr.'-01-01',$prev_yr.'-12-31');
$stmt->execute();
}
I can't test it so hopefully I got everything in the right place.
As I said I don't think you can bind to the Fields part of the query and certainly not inside a partial string, besides it's making a select that is un-needed. Just make sure to prepare the insert before the loop.
Just to clearly the only thing that select actually gets from the DB is this
select StudentID ... from student Where StudentID in (?)
The rest are added in as "fake" columns, I don't know the term for it. It's difficult to read the original query..
I am wondering if there is a way of binding the $prev_yr once for all 3 occurrences.
No.
Besides, it wouldn't work this way anyway, as you cannot bind just an arbitrary query part of your choice. You can bind a complete data literal only. Means instead of '?-01-01' it should be just ?, whereas in your PHP code you should make it
$dateStart = "$prev_yr-01-01";
and then bind this variable for the whole value. So there will be no more repeating variables.

how to insert decimal data type into sql server from php

This error annoyed me
[SQLSTATE] => 42000
[code] => 8114
[message] => [Microsoft][ODBC Driver 11 for SQL Server][SQL Server]Error converting data type varchar to numeric.
when i remove ' ' this it display
[SQLSTATE] => 42000
[code] => 102
[message] => [Microsoft][ODBC Driver 11 for SQL Server][SQL Server]Incorrect syntax near ','.
I try to insert amount data from web page(PHP), but I don't know if I can use CAST or CONVERT
if ($_SERVER['REQUEST_METHOD'] =='POST' && isset($_POST['save']))
{
$save = "INSERT INTO trans_details
(badge_id,user_id,comp_id,amount,cash,subsidy,trans_date)
values('$badge_id','$user_id','$cid','$amount','$total_need','$amount',$stamp)";
$result = sqlsrv_query($conn, $save);
}
meanwhile, At the my database amount and total_need are declared as decimal(12,2). And I tried to use isNumeric() function but it store value 1? What can I do to store directly from php?
Here's another good reason to use prepared statements. Try this out:
if (isset($_POST["save"])) {
$query = "INSERT INTO trans_details (
badge_id, user_id, comp_id, amount, cash, subsidy, trans_date
)
VALUES (?, ?, ?, ?, ?, ?, ?)";
$parameters = [$badge_id, $user_id, $cid, $amount, $total_need, $amount, $stamp];
$result = sqlsrv_query($conn, $query, $parameters);
}
This will avoid any problems with quoting, and make your queries safer.
For insert numeric value don't add '' over value
$save = "INSERT INTO trans_details
(badge_id,user_id,comp_id,amount,cash,subsidy,trans_date)
values('$badge_id','$user_id','$cid',$amount,$total_need,'$amount',$stamp)";
$result = sqlsrv_query($conn, $save);
This is a problem of localization/regional settings, you probably have configured PHP with a locale that uses a comma (,) for the decimal point separator instead of a dot (.) , for example supposing that $product_id is 1 and $price is 1.23 when you do:
$sql_insert = "INSERT INTO products (product_id, price) values ($product_id,$price)";
your are getting:
INSERT INTO Products VALUES (1,1,23) -- three values: 1, 1 and 23
instead of:
INSERT INTO Products VALUES (1,1.23) -- two values: 1 and 1.23
Possible solutions:
Use prepared statements instead of creating the query string manually. This also helps protect you from SQL injection.
If for any reason you can't use prepared statements use number_format() for converting the values to string, that function has an optional parameter for specifying the decimal point character (also set the thousands separator as '').
Change the locale of PHP with set_locale(), note that this will affect all conversions, so maybe is not an option for you if you need to output numbers formatted with your current locale.

How to subtract two sql datetime fields

I have two datetime values on sql database and I want to subtract them and get the difference as a number of hours.
So far I have created three values. Deptime and ArrTime as datetime values and here are my questions.
1) What value shall the third table be? can it be number because I want to use it for statistics?
2) How can I subtract the Deptime and Arrtime and store the differnce in the FlightTime?
Thanks in advance
DATEDIFF can get you your hours.
SELECT DATEDIFF(HOUR, Deptime,Arrtime ) AS FlightTime FROM YourTable.
If you are using tSQL then you could use the DATEDIFF function. You can use this function with hours but if you want fractions of hours then you can use minutes and then convert back to hours.
fraction of hours
SELECT CAST(DATEDIFF(MINUTE, Deptime,Arrtime) AS DECIMAL(30,10))/60 AS FlightTime
FROM TableName
whole hours
SELECT CAST(DATEDIFF(HOUR, Deptime,Arrtime)) AS FlightTime
FROM TableName
Since it is a calculated field, I would just create a view with the DATEDIFF function for the calculated field.
PHP has its own DateInterval routines that might give you more flexibility (and portability) than doing it in SQL.
$datetime1 = new DateTime($DepDate);
$datetime2 = new DateTime($ArrDate);
$FlightTime = $interval->format('%h');
I'm looking at your progress and see a couple of red flags. Since you're accepting user input and inserting it into a database, you should at the very least be using prepared, parameterized insert statements.
$PiRepSubmissionSqlQuery = '
INSERT INTO Pireps (
PID, FLID, DEPID, ARRID,
FlightPlan, AircraftType, Fuel,
DepDate, ArrDate, FlightTime,
Remarks, Server
)
VALUES (
?, ?, ?, ?,
?, ?, ?,
?, ?, ?,
?, ?
)
';
// This is just an example - don't forget to check for errors
$sth = mysqli_prepare($mydb, $PiRepSubmissionSqlQuery);
mysqli_stmt_bind_param(
$sth,
'iiiisssssiss', // these should correspond to your SQL datatypes
$PID, $FLID, $DEPID, $ARRID,
$FlightPlan, $AircraftType, $Fuel,
$DepDate, $ArrDate, $FlightTime,
$Remarks, $Server
);
mysqli_stmt_execute($sth);
You should use mysql function TIMESTAMPDIFF to get difference between dates. So your query should look like this:
$PiRepSubmissionSqlQuery = "INSERT INTO Pireps (PID, FLID, DEPID, ARRID, FlightPlan, AircraftType ,Fuel ,DepDate ,ArrDate, FlightTime ,Remarks ,Server)
VALUES ('$PID', '$FLID', '$DEPID', '$ARRID','$FlightPlan' ,'$AircraftType' ,'$Fuel','$DepDate' ,'$ArrDate' ,TIMESTAMPDIFF(HOUR, ArrDate, DepDate), '$Remarks' ,'$Server')";

Send delimited string via JSON to PHP for prepared statements

For example i send the following id:
$user->id = '1{3}4{5}6';
Represents:
$user->id(=1{3}4{5}6){$option(=3)}$value(=4){$option(=5)}$value(=6)
I now need to insert to database using prepared statements for each $option and $value pair.
the sql looks as following:
if ($user->attr == 1) {
$sth = $this->dbh->prepare("insert into customers_basket_attributes
(customers_id,
products_id,
products_options_id,
products_options_value_id)
values ('1', ?, ?, ?)");
$sth->execute(array($user->id, $option, $value));
return json_encode(1);
}
I want to avoid falling back to jQuery for each db insertion.
as far as I understand, this $user->id = '1{3}4{5}6'; decomposes:
Product_id = 1
Option_3 = 4
Option_5 = 6
and you want to store that in to records like:
products_id products_options_id products_options_value_id
1 3 4
1 5 6
From my point of view, you basically need as much inserts as you have rows above. You may combine that in to one insert with multiple rows:
insert into customers_basket_attributes
(customers_id,
products_id,
products_options_id,
products_options_value_id)
values (nn, 1,3,4),(nn, 1,5,6)
putting this into a prepared statement is somehow fiddling around with arrays, but should be achievable. Probably its clearer to just issue one insert per row, the cost is marginal anyway.

Categories