Update over 100 fields in mysql - php

i have 181 fields in my database named S1, S2....S181. I want to update these fields using values from inputs WITH name="S1", .....NAME="S181".
MY CODE IS
$S1=$_POST['S1'];
...
...
$S181=$_POST['S181'];
$sql=mysqli_query($conn,"update 'cap' set S1='$S1'......S181='$S181'")
I am trying something like
for ($i = 1; $i<=181; $i++ ) {
$(S$i)=$_POST['S$i'];
$sql = mysqli_query($conn, "UPDATE `cap4a` SET
S$i='$(S$i)'
WHERE IDID=".$id) or die (mysqli_error($conn));
}
Is there something wrong in the way I use S$i, because I am getting errors:
"Parse error: syntax error, unexpected '(', expecting variable (T_VARIABLE) or '$' in C:\xampp1\htdocs\update_cap4a.php on line 5" ?

I don't think it's a good idea to run 181 queries to alter the same row as you do. Instead, run one query that makes all required changes to the row. The code below will work for you:
$id = (int)$_POST['id'];//remove (int) if id IDID is a string
$snippets = [];//holds little snippets eg: S1='value1'
for($i=1;$i<=181;$i++){
$varname = "S$i"; //S1...S181
if(!isset($_POST[$varname])) continue;
$snippets[] = " $varname='$_POST[$varname]' ";
}
$sql = '"UPDATE cap SET '.implode(",",$snippets)." WHERE IDID=$id";
$result = mysqli_query($conn,$sql) or die (mysqli_error($conn));
I don't cover it in this snippet but you need to add at least two things before using this in production:
Proper error handling, for when your query fails
Prepared statements or escaped values to protect against SQL injection
Is there something wrong in the way I use S$i
To dynamically create a variable named S10 and set it to 'value' when $i=10, do:
$varname = "S$i";
$$varname = 'value'; // $$varname can also be referred to as $S10
See Variable Variables in the docs.

I would gave done it this way:
for ($i = 1; $i<=181; $i++) {
$key = 'S'.$i;
$value = $_POST[$key];
$update[] = "`{$key}` = '".$value."'";
$sql = mysqli_query($conn, "UPDATE `cap4a` SET ".join(",",$update)."
WHERE IDID=".$id) or die (mysqli_error($conn));
}

Related

Mistake in SQL syntax.. (bindValue?)

I am trying to create an update query and I am looping in some set stuff to a var called $str and I cant seem to get it to work.
if (is_numeric($id)) {
if (!empty($values) && !empty($table_name)) {
$str = '';
$sql = "UPDATE `$table_name` SET :update_values WHERE `$column_name` = :id";
// Its one because we dont use ID like that
$i = 1;
foreach ($values as $key => $value) {
if ($key != $column_name) {
// Exclude the last one from having a comma at the end
if ($i == count($values) - 1) {
$str .= "$key='" . $value . "'";
} else {
$str .= "$key='" . $value . "', ";
$i++;
}
}
}
$query = $this->dbh->prepare($sql);
$query->bindValue('update_values', $str, PDO::PARAM_STR);
$query->bindValue(':id', $id, PDO::PARAM_INT);
$query->execute();
return true;
} else {
return false;
}
} else{
return false;
}
}
Output:
Fatal error: Uncaught PDOException: SQLSTATE[42000]: Syntax error or
access violation: 1064 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 ''note_name=\'yeet\', note_date=\'2020-02-20\',
note_desc=\'asdasdasdasdadsasdads' at line 1
Am I making any obvious mistakes?
Also for the life of me I don't know what the backslashes in front of the values mean.
In MySQL, identifiers cannot be provided as values.
References to columns must appear in the text of the SQL statement, they cannot be provided through bind parameters. This holds true for table names, column names, function names.
There is no workaround; this is a by-design restriction. There's several reasons for this. One of the most straightforward reasons is understanding how a SQL statement gets prepared, the information that is needed to come up with an execution plan, the tables and columns have to be known at prepare time (for the semantic check and privilege check. The actual values can be deferred to execution time.
Bind placeholders are for providing values, not identifiers.
With the code given, what MySQL is seeing something along the lines of
UPDATE `mytable` SET 'a string value' WHERE `id_col` = 42
And MySQL is balking at the 'a string value'.
We can (and should) use bind parameters for values.
We could dynamically generate SQL text that looks like this:
UPDATE `mytable`
SET `col_one` = :val1
, `col_two` = :val2
WHERE `id_col` = :id
and after the SQL text is prepared into statement, we can bind values:
$sth->bindValue(':val1', $value_one , PDO::PARAM_STR );
$sth->bindValue(':val2', $value_two , PDO::PARAM_STR );
$sth->bindValue(':id' , $id , PDO::PARAM_INT );
and then execute

using form variables for mysql query

I'm trying to fetch a result from a mysql table using two form variables namely $sessionID and $semesterID. I used the following code and it seems to have an error in the sql syntax
<?php
...
mysql_select_db($database_connChePortal, $connChePortal);
$query_rsRegcourses =sprintf("SELECT * FROM VW_reg vwr WHERE vwr.sessionID=%s AND vwr.semesterID=%s",$sessionID,$semesterID);
$rsRegcourses = mysql_query($query_rsRegcourses, $connChePortal) or die(mysql_error());
$row_rsRegcourses = mysql_fetch_assoc($rsRegcourses);
$totalRows_rsRegcourses = mysql_num_rows($rsRegcourses);
print_r($query_rsRegcourses); die;
...
?>
I tried running the query and I have the following error report
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 'AND vwr.semesterID=' at line 1
thanks
I think you should surround your variable with single quotes '' please change as follow
"SELECT * FROM VW_reg vwr WHERE vwr.sessionID='%s' AND vwr.semesterID='%s'"
Put the %s in single quotes like this
"SELECT * FROM VW_reg vwr WHERE vwr.sessionID='%s' AND vwr.semesterID='%s'",$sessionID,$semesterID);
To insert a variable into query, you have to properly format it.
Two other answers contains improper formatting - so, you shouldn't follow them.
To make formatting more handy, you have to encapsulate sprintf() into function like this:
function paraQuery()
{
$args = func_get_args();
$query = array_shift($args);
$query = str_replace("%s","'%s'",$query);
foreach ($args as $key => $val)
{
$args[$key] = mysql_real_escape_string($val);
}
$query = vsprintf($query, $args);
$result = mysql_query($query);
if (!$result)
{
throw new Exception(mysql_error()." [$query]");
}
return $result;
}
which would apply proper formatting and also will handle errors
Also note that your way of counting records is extremely inefficient and may cause server to hang. You have to query the only data you need. So, if you need only count - request the count only
so, the code would be
mysql_select_db($database_connChePortal, $connChePortal);
$sql = "SELECT count(*) FROM VW_reg vwr WHERE vwr.sessionID=%s AND vwr.semesterID=%s";
$res = paraQuery($sql,$sessionID,$semesterID);
$row = mysql_fetch_row($res);
print_r($row[0]); die;
it will make your query properly formatted and thus invulnerable to SQL injection
also, it seems that $semesterID is not set which may cause some problem too

PHP Works but gives sql SYNTAX error

I just wrote this bit of code which echo's out what it's supposed to but after the echo statement it give me the error-
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 '' at line 1
why's this happening? how do i fix it?
<?php
$myclasses = explode(',', $_SESSION['classlist']);
$theirclasses = explode(',', $user_info['classlist']);
$common_classes = array_intersect($myclasses, $theirclasses);
if (count($common_classes) > 0) {
foreach ($common_classes as $class) {
$classes = mysql_query("SELECT * FROM classes WHERE class_id = ".$class) or die(mysql_error());
while($currentRow = mysql_fetch_array($classes)){
echo $currentRow['class_name'];
}
}
}
else {
}
?>
Try wrapping your query with quote:
$classes = mysql_query("SELECT * FROM classes WHERE class_id = '".$class."'") or die(mysql_error());
or change your query altogether by using PDO. Because, mysql_* function are deprecated.
I am going to assume that something is wrong in the $class variable when passed to the query. What I usually do in such scenarios is assign the SQL query to a string variable and dump it to test the entire query at once. Helps me find out SQL syntax errors or if there's any undesired characters.
<?php
$myclasses = explode(',', $_SESSION['classlist']);
$theirclasses = explode(',', $user_info['classlist']);
$common_classes = array_intersect($myclasses, $theirclasses);
if (count($common_classes) > 0) {
foreach ($common_classes as $class) {
$sql = "SELECT * FROM classes WHERE class_id = '{$class}'" ; // use {} inside double quotes
var_dump($sql); // check out the what the query becomes
$classes = mysql_query($sql) or die(mysql_error());
while($currentRow = mysql_fetch_array($classes)){
echo $currentRow['class_name'];
}
}
}
else {
}
If $class is empty you'd get that error which would leave your query as SELECT * FROM classes WHERE class_id = which is not valid. Try quote it. If you quote it, at least you'll get SELECT * FROM classes WHERE class_id = ''
"SELECT * FROM classes WHERE class_id = '".$class."'";

I don't understand how "?" is being used here

So, I have this PHP code:
$tabid = getTabid($module);
if($tabid==9)
$tabid="9,16";
$sql = "select * from field ";
$sql.= " where field.tabid in(?) and";
Now, how exactly does the ? work here? I vaguely understand that in PHP, ?: is a ternary operator, but the colon isn't being used here, and ? is part of a Postgresql query anyway.
The final query looks a bit like this:
select * from field where field.tabid in('9,16')
So, the question mark is replaced by the contents of $tabid, how does that happen?
The issue is that ('9,16') is not accepted by Postgres as an integer, it needs to be written like (9,16), so how do I do that? How do I remove the apostrophes?
Thanks a lot for the help, have a good day!
edit: More code was requested:
$sql.= " field.displaytype in (1,2,3) and field.presence in (0,2)";
followed by if statements, I think this is the relevant one:
if($tabid == 9 || $tabid==16)
{
$sql.= " and field.fieldname not in('notime','duration_minutes','duration_hours')";
}
$sql.= " group by field.fieldlabel order by block,sequence";
$params = array($tabid);
//Running the query.
$result = $adb->pquery($sql, $params);
Oh, I think I see now, I think it is a place holder, a part of the pquery function:
function pquery($sql, $params, $dieOnError=false, $msg='') {
Stuff
$sql = $this->convert2Sql($sql, $params);
}
Now, this is where it seems to get fun, here's part of the convert2Sql function:
function convert2Sql($ps, $vals) {
for($index = 0; $index < count($vals); $index++) {
if(is_string($vals[$index])) {
if($vals[$index] == '') {
$vals[$index] = "NULL";
}
else {
$vals[$index] = "'".$this->sql_escape_string($vals[$index]). "'";
}
}
}
$sql = preg_replace_callback("/('[^']*')|(\"[^\"]*\")|([?])/", array(new PreparedQMark2SqlValue($vals),"call"), $ps);
return $sql;
}
The problem I think lies in the
$vals[$index] = "'".$this->sql_escape_string($vals[$index]). "'"; line.
The sql_escape_string($str) function just returns pg_escape_string($str).
Sorry for the super long edit, but I still haven't been able to get past I am afraid, thanks for all the help!
Edit 2: I fixed the problem, all it took was changin $tabid = "9,16" to $tabid = array(9,16). I have no idea why, oh and I also had to remove the group by statement because Postgresql requires every field to be placed in that statement.
it is a positional parameter for a prepared statement
See: http://php.net/manual/en/function.pg-prepare.php
You don't actually 'remove' the quotes, you have to pass SQL array of ints instead of a string value into the parameter when doing pg_execute
An example:
// Assume that $values[] is an array containing the values you are interested in.
$values = array(1, 4, 5, 8);
// To select a variable number of arguments using pg_query() you can use:
$valuelist = implode(', ', $values);
// You may therefore assume that the following will work.
$query = 'SELECT * FROM table1 WHERE col1 IN ($1)';
$result = pg_query_params($query, array($valuelist))
or die(pg_last_error());
// Produces error message: 'ERROR: invalid input syntax for integer'
// It only works when a SINGLE value specified.
Instead you must use the following approach:
$valuelist = '{' . implode(', ', $values . '}'
$query = 'SELECT * FROM table1 WHERE col1 = ANY ($1)';
$result = pg_query_params($query, array($valuelist));

mysql_num_rows error in PHP with mysql_query

Hi i am too new too php and mysql and i want to count the member number due to the search made by user. However, mysql_num_rows doesnt work.
mysql_num_rows(mysql_query("SELECT * FROM members WHERE $title LIKE '%$_POST[search]%' LIMIT $start,$member_number"));
It says "mysql_num_rows(): supplied argument is not a valid MySQL result resource in ..."
NOTE: $title is a select menu which user choose where to search. LIMIT is, as you know :), number of member which is shown in a page.
And also $start= ($page-1)*$member_number; in order to set the first entry in that page. I think the problem is here but i cant solve it. :(
Your query probably has an error, in which case mysql_query will return false.
For this reason, you should not group commands like this. Do it like this:
$result = mysql_query("...");
if (!$result)
{ echo mysql_error(); die(); } // or some other error handling method
// like, a generic error message on a public site
$count = mysql_num_rows($result);
Also, you have a number of SQL injection vulnerabilities in your code. You need to sanitize the incoming $search variable:
$search = mysql_real_escape_string($_POST["search"]);
... mysql_query(".... WHERE $title LIKE '%$search%'");
if $start and $end come from outside, you also need to sanitize those before using them in your LIMIT clause. You can't use mysql_real_escape_string() here, because they are numeric values. Use intval() to make sure they contain only numbers.
Using a dynamic column name is also difficult from a sanitation point of view: You won't be able to apply mysql_real_escape_string() here, either. You should ideally compare against a list of allowed column names to prevent injection.
you have to use GET method in your form, not POST.
mysql_num_rows doesn't make sense here.
If you're using limit, you already know the number*.
If you want to know number, you shouldn't use limit nor request rows but select number itself.
// get your $title safe
$fields = array("name","lastname");
$key = array_search($_GET['title'],$fields));
$title = $fields[$key];
//escape your $search
$search = mysql_real_escape_string($_GET['search']);
$sql = "SELECT count(*) FROM members WHERE $title LIKE '%$search%'";
$res = mysql_query($query) or trigger_error(mysql_error()." in ".$sql);
$row = mysql_fetch_row($res);
$members_found = $row[0]
in case you need just 5 records to show on the page, no need for mysql_num_rows() again:
// Get LIMIT params
$member_number = 5;
$start = 0;
if (isset($_GET['page'])){
$start = abs($_GET['page']-1)*$member_number;
}
// get your $title safe
$fields = array("name","lastname");
$key = array_search($_GET['title'],$fields));
$title = $fields[$key];
//escape your $search
$search = mysql_real_escape_string($_GET['search']);
$sql = "SELECT count(*) FROM members
WHERE `$title` LIKE '%$search%'
LIMIT $start, $member_number";
$res = mysql_query($query) or trigger_error(mysql_error()." in ".$sql);
while($row = mysql_fetch_assoc($res){
$data[] = $row;
}
Now you have selected rows in $data for the further use.
This kind of error generally indicates there is an error in your SQL query -- so it has not been successful, and mysql_query() doesn't return a valid resource ; which, so, cannot be used as a parameter to mysql_num_rows().
You should echo your SQL query, in order to check if it's build OK.
And/or, if mysql_query() returns false, you could use mysql_error() to get the error message : it'll help you debug your query ;-)
Typically, your code would look a bit like this :
$query = "select ..."; // note : don't forget about escaping your data
$result = mysql_query($query);
if (!$result) {
trigger_error(mysql_error()." in ".$query);
} else {
// use the resultset
}

Categories