Mysql how to replace multiple values in 1 Column - php

My table has a column titled Views with last weeks values.
I want to replace these old values with new values, all of them.
I have tried
UPDATE `Table` SET `views`=35490904, 4013, 1867953, 21558, 12237;
&
REPLACE INTO `Table` (views) VALUES (35490904, 4013, 1867953, 21558, 12237);
where am I going wrong?

Have a look at the sql-syntax for UPDATE:
UPDATE views SET property1=35490904, property2=4013, property3=1867953, property4=21558, property5=12237 WHERE ...;
You have to replace the property parts with the real names of your table columns. I assumed that these are all integers, so if these should be inserted as strings add the ' around the values.
In the WHERE part you can specify wich rows should be updated. If you leave it empty all rows will be updated with the given values.

You cannot UPDATE multiple rows with different values in one statement. You will need multiple queries.
<?php
$values = array
(
/* row_id => column_value */
);
// Example code using PDO, feel free to use msqli instead
$db = /* Get database object instance */
$query = $db->prepare('UPDATE Table SET views=:column_value WHERE id=:row_id');
foreach($values as $row_id => $column_value)
{
$result = $query->execute(array(
':row_id' => $row_id,
':column_value' => $column_value
));
/* Confirm that $return is TRUE/check for errors if desired */
}

Related

add data from txt file to mysql column by column (php- PDO)

I have a TXT file with no punctuation between them. I would like to shred this file by the table column widths in the database and save it.
Let me tell you this step by step…
I’m creating a table in the database with my tabloolustur.php page. The column numbers and column widths of the tables I create will not be the same.
There are no punctuation marks between the TXT file data. First, I want to split the TXT file rows by column width.
$result = $baglanti->prepare("SHOW COLUMNS FROM customers where Field NOT IN('id')");
$result->execute();
$colcount = $result->columnCount()-1;
$columLen = array();
foreach($result as $key => $col){
preg_match('/\d+/', $col['Type'], $len);
$len = (isset($len[0]))? $len[0] : '';
$fieldname = $col['Field'];
$columLen[$fieldname] = $len;
}
For this, I get the number of columns and column widths with the code.
Then, I separate the data with commas with the following function.
function txtBol($metin, $genislik){
$parcala=array();
foreach ($genislik as $sutunadi => $lenght)
{
$parcala[$sutunadi] = substr($metin, 0, $lenght);
$metin = substr($metin, $lenght);
}
return $parcala;
}
I also get column names with the following code. (ps: to use in a query)
$KolAdi = $baglanti->query("SHOW COLUMNS FROM customers where Field NOT IN('id')");
$KolAdi->execute();
$colonAdi= $KolAdi->fetchAll(PDO::FETCH_COLUMN);
$colonAdi=implode(',', $colonAdi);
It prints the data i split correctly when printing it to the screen. So far, so good. But I can’t create the right query with PDO. How should I create the query? (ps: Table column names and column widths are not the same. There will be different numbers and width columns for each table)
I would appreciate it if you could help. I proceeded by implementing some solutions from your site.
Table:
id
name
cev1
cev2
cev3
1
MARTIN EDEN
AAAAAA
BBBBB
CCCC
txt:
MARTIN EDEN........AAAAAABBBBBDDDD
Assuming a valid PDO connection in $PDO, you can do the whole job like this.
It reads the column data once and uses that to create a query to prepare and a regular expression to extract the data.
$table = 'customer';
$txtFile = 'cust.txt';
// No need to prepare this since there's no untrusted data here.
$result = $pdo->query("show columns from `$table` where Field <> 'id'");
// Get column names and widths in arrays
while($columns = $result->fetch(PDO::FETCH_ASSOC)) {
$colNames[] = $columns['Field'];
preg_match('/\d+/', $columns['Type'], $len);
$colLengths[] = $len[0]??'';
}
// Create regex to extract data from lines:
// Looks like this: /(.{20})(.{10})(.{5})/
$regex = '/(.{'.implode('})(.{',$colLengths).'})/u';
// Create skeleton query with table name and field names and placeholders
// Looks like this: INSERT customer (name,addr1,postcode) VALUES (?,?,?)
$query = "INSERT $table (`".implode('`,`', $colNames).'`) VALUES ('.str_repeat('?,', count($colNames)-1).'?)';
// Read text file
if ($fileData = file($txtFile)) {
// Prepare the query only once
$stmt = $pdo->prepare($query);
foreach ($fileData as $row) {
// Get the data using the regex from above
preg_match($regex, $row, $rowData);
// Remove the first row of the regex matches - see PHP manual for why
array_shift($rowData);
// Now execute the prepared query using the data extracted by the regex.
$stmt->execute($rowData);
}
}
Note that this codes assumes that the table consists of a series of contiguous columns from which it can extract column widths, and no other columns except id, which it ignores. If your actual table structure is different you'll need to modify the SHOW COLUMNS query to omit those columns, or modify the code that extracts the column data to extract only the relevant columns.
{Edit]
Updated the code to include /u UTF-8 modifier on the regex, and to wrap the column names in the INSERT query in back ticks.
you can create a table like this and you don't need to check a number of fields by rows
let me know if this useful
CREATE TABLE new_table (
id INT NOT NULL AUTO_INCREMENT,
row_id INT NULL DEFAULT 0,
row_field_name VARCHAR(50) NULL DEFAULT NULL COMMENT 'Index of ',
row_value VARCHAR(255) NULL DEFAULT NULL,
PRIMARY KEY (id));

Create array with key and value in loop PHP

I'm using PDO, and I managed to get the table columns despite the table name and create the bind variables, like in ... VALUES (:foo, :bar);.
The method I'm trying to do this is insert().
public function insert()
{
// the variable names depend on what table is being used at the moment the script runs.
// These methods use the PDO `getColumnMeta()` to retrieve the name of each column
$sql = "INSERT INTO {$this->getTableName()}({$this->getTableColumns()}) "
. "VALUES ({$this->getTableColumns(true)})";
// The previous method gets the name of each column and returns a single string, like "foo, bar, [...]"
// and this function is used to separate each word, with the specified delimiter
$col = explode(", ", $this->getTableColumns());
// Now here lays the problem.
// I already know how to retrieve the columns name as a variable, and
// how to dynamically create the get method, using `ucfirst()`
// What I need would be something like this being inside of a
// loop to retrieve all the separated words from `$col` array.
$data = array(
$col[$i] => "\$this->entity->get".ucfirst($col[$i])."()",
)
/*
* From now on, is what I need to do.
*/
// Lets pretend the column names are "foo, bar".
$data = array(
":foo" => $this->entity->getFoo(),
":bar" => $this->entity->getBar()
)
// That'd be the final array I need, and then continue with
$stm = $this->db->prepare($sql);
$stm->execute($data);
}
You have to loop over $data array and add function as per your requirement.
Fetch values from `... VALUES (:foo, :bar); Then explode as you did in your code , then loop over $col array and add values to $data as required
foreach($col as $val){
$method = "get".ucfirst( $val);
$data[ $val] = call_user_func(array( $this->entity,$method));
}
Above code may work as follow
$data[':foo'] = $this->entity->getFoo();
$data[':bar'] = $this->entity->getBar();

cast text field to array in mysql select query

I have a table in MySQL database. In that table there is a text field called 'selection' that hold numbered values, separated by a pipe char (example: 44|5|23|546|.....). I also have a php array: $values = array(63,35,7,5);
I need to refer to the 'selection' field as array of options (separated by '|') and select only the rows that contain at least one of the number in $values array.
I hope i explained my problem accurately enough, because my English is very poor... Thanks.
If you want to get row that contains at least one number in $values array, the SQL looks like this:
$values = array(63,35,7,5);
foreach ($values as $value) {
$sql = "select * from tablename where selection like '%{$value}|%' or '%|{$value}%'";
}
If the values in the array are in the appropriate order for search already, you can build your query with something like this:
$selection_searched = implode('|', $values);
$query = "SELECT * FROM your_table WHERE selection = '$selection_searched'";
Beware that you would probably want to validate the array $values fisrt, to check if it isn't empty, etc. Check out the manual for: http://php.net/implode

Insert unknown number of rows into MySQL using PHP

I am trying to insert an unknown number of rows into MySQL using PHP. This is how it should work:
Javascript parses HTML DOM to create a multi-dimensional array based on a css class. The array will have a certain number of rows(or sub-arrays) corresponding to the number of elements that have that class. (This could be any integer 0 or greater... obviously).
Then, on a JavaScript event, the array is sent to a PHP script.
The PHP script will INSERT data from the array into MySQL.
My problem is that I don't know how to tell my PHP script how many values are in the array. And I don't know how to write the mysql_query() without knowing the number of values (or rows) that should be inserted.
You can insert more than one row at a time to MySQL:
INSERT INTO table1 (column1, column2, ...) VALUES (value_col1, value_col2), (value2_col1, value2_col2), ...;
In PHP, you can build your query by looping through rows and adding them to the SQL string:
$sql = "INSERT INTO table1 (col1, col2) VALUES ";
foreach($rows as $i=>$row) {
if ($i>0) {
$sql .= sprintf(",(%s,%s)", $row["col1_value"], $row["col2_value"]);
} else {
$sql .= sprintf("(%s,%s)", $row["col1_value"], $row["col2_value"]);
}
}
mysql_query($sql);
You have to be sure to properly escape your values depending upon what you're actually inserting.
Why don't you prepare a two dimensional array while searching with the css class identifier like this?
//This is jquery code - you can write javascript to do the same
$(`.class`).each(function(i,e){resultsArray.push($(this).val());});
This will save you from the headache of traversing a multidimensional array in the backend and you can simply do a count() in you PHP code and the following query preparation.
Query preparation
Assuming you have a two dimensional array you can use a bulk insert query like this:-
INSERT INTO tablename (a,b)
VALUES
('1', 'one'),
('2', 'two'),
('3', 'three')
And prepare the query dynamically using PHP like this -
$counter = 0;
$valuesPart = NULL;
foreach($_POST as $each)
{
if($counter > 0)
$appendComma = ",";
else
$appendComma ="";
$valuesPart .= $appendComma."(".$each['key1'].",".$each['key2'].")";
$counter++;
}
if(!empty($valuesPart))
$mysql_query = "INSERT INTO tablename (a,b) VALUES ".$valuesPart;
So, you don't need to know how many results are to be actually inserted.
If you stay with the multidimensional array, you will probably need to code or search for a code to traverse the multidimensional array which will probably involve recursion and a lot of complex code. There will be many chances of errors and it will be a slower (may be little but a finite amount which is not necessary).
So I assume the array is getting to PHP successfully, through $_POST or whatever? If you aren't sure then do a var_dump or echo_r so we can see.
EDIT - wow I put explode where I meant implode several times. fixed.
Assuming that it is, and that each 'sub' array is an associative array in form
[0]
'id' => 1
'name' => 'Billy'
'DOB' => .....
[1]
etc.
And the code to build a single query inserting all rows, like this INSERT INTO table ('f1','f2',f3') VALUES ('v11', 'v22', 'v33'), ('v21', 'v22', 'v23'), ......
$escapeAndQuote = function($x) {return "'".mysql_real_escape_string($x)."'";};
$rowwise = function($x) {return '('. implode(', ', array_map($escapeAndQuote, $x)) .')';
$fieldString = $rowwise(array_keys($arr[0]));
$valString = implode(', ', array_map($rowwise, $arr));
$sql = "INSERT INTO table $fieldString VALUES $valString";
mysql_query($sql, $conn);
Use a foreach loop to cycle through the array.
// Example:
foreach($submitted_array as $insert_array)
{
//php and mysql insert query here
}
Perhaps prepared statements would assist you in your endeavors. Essentially you will declare a generic insert statement and then "bind" values to each input. Read more on PHP PDO Prepared Statements.

how to identify the source table of fields from a mysql query

I have two dynamic tables (tabx and taby) which are created and maintained through a php interface where columns can be added, deleted, renamed etc.
I want to read all columns simulataneously from the two tables like so;-
select * from tabx,taby where ... ;
I want to be able to tell from the result of the query whether each column came from either tabx or taby - is there a way to force mysql to return fully qualified column names e.g. tabx.col1, tabx.col2, taby.coln etc?
In PHP, you can get the field information from the result, like so (stolen from a project I wrote long ago):
/*
Similar to mysql_fetch_assoc(), this function returns an associative array
given a mysql resource, but prepends the table name (or table alias, if
used in the query) to the column name, effectively namespacing the column
names and allowing SELECTS for column names that would otherwise have collided
when building a row's associative array.
*/
function mysql_fetch_assoc_with_table_names($resource) {
// get a numerically indexed row, which includes all fields, even if their names collide
$row = mysql_fetch_row($resource);
if( ! $row)
return $row;
$result = array();
$size = count($row);
for($i = 0; $i < $size; $i++) {
// now fetch the field information
$info = mysql_fetch_field($resource, $i);
$table = $info->table;
$name = $info->name;
// and make an associative array, where the key is $table.$name
$result["$table.$name"] = $row[$i]; // e.g. $result["user.name"] = "Joe Schmoe";
}
return $result;
}
Then you can use it like this:
$resource = mysql_query("SELECT * FROM user JOIN question USING (user_id)");
while($row = mysql_fetch_assoc_with_table_names($resource)) {
echo $row['question.title'] . ' Asked by ' . $row['user.name'] . "\n";
}
So to answer your question directly, the table name data is always sent by MySQL -- It's up to the client to tell you where each column came from. If you really want MySQL to return each column name unambiguously, you will need to modify your queries to do the aliasing explicitly, like #Shabbyrobe suggested.
select * from tabx tx, taby ty where ... ;
Does:
SELECT tabx.*, taby.* FROM tabx, taby WHERE ...
work?
I'm left wondering what you are trying to accomplish. First of all, adding and removing columns from a table is a strange practice; it implies that the schema of your data is changing at run-time.
Furthermore, to query from the two tables at the same time, there should be some kind of relationship between them. Rows in one table should be correlated in some way with rows of the other table. If this is not the case, you're better off doing two separate SELECT queries.
The answer to your question has already been given: SELECT tablename.* to retrieve all the columns from the given table. This may or may not work correctly if there are columns with the same name in both tables; you should look that up in the documentation.
Could you give us more information on the problem you're trying to solve? I think there's a good chance you're going about this the wrong way.
Leaving aside any questions about why you might want to do this, and why you would want to do a cross join here at all, here's the best way I can come up with off the top of my head.
You could try doing an EXPLAIN on each table and build the select statement programatically from the result. Here's a poor example of a script which will give you a dynamically generated field list with aliases. This will increase the number of queries you perform though as each table in the dynamically generated query will cause an EXPLAIN query to be fired (although this could be mitigated with caching fairly easily).
<?php
$pdo = new PDO($dsn, $user, $pass, array(PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION));
function aliasFields($pdo, $table, $delim='__') {
$fields = array();
// gotta sanitise the table name - can't do it with prepared statement
$table = preg_replace('/[^A-z0-9_]/', "", $table);
foreach ($pdo->query("EXPLAIN `".$table."`") as $row) {
$fields[] = $table.'.'.$row['Field'].' as '.$table.$delim.$row['Field'];
}
return $fields;
}
$fieldAliases = array_merge(aliasFields($pdo, 'artist'), aliasFields($pdo, 'event'));
$query = 'SELECT '.implode(', ', $fieldAliases).' FROM artist, event';
echo $query;
The result is a query that looks like this, with the table and column name separated by two underscores (or whatever delimeter you like, see the third parameter to aliasFields()):
// ABOVE PROGRAM'S OUTPUT (assuming database exists)
SELECT artist__artist_id, artist__event_id, artist__artist_name, event__event_id, event__event_name FROM artist, event
From there, when you iterate over the results, you can just do an explode on each field name with the same delimeter to get the table name and field name.
John Douthat's answer is much better than the above. It would only be useful if the field metadata was not returned by the database, as PDO threatens may be the case with some drivers.
Here is a simple snippet for how to do what John suggetsted using PDO instead of mysql_*():
<?php
$pdo = new PDO($dsn, $user, $pass, array(PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION));
$query = 'SELECT artist.*, eventartist.* FROM artist, eventartist LIMIT 1';
$stmt = $pdo->prepare($query);
$stmt->execute();
while ($row = $stmt->fetch()) {
foreach ($row as $key=>$value) {
if (is_int($key)) {
$meta = $stmt->getColumnMeta($key);
echo $meta['table'].".".$meta['name']."<br />";
}
}
}

Categories