How to insert data in table from RETS search query? - php
I am trying to insert data in a table. I am using a search query and then FetchRow in while condition to fetch the data in row and want to insert this row in a table directly. I have given the structure of table in this link.
The code for insert values in table in while condition is here:
require_once (ABSPATH . 'wp-admin/includes/upgrade.php');
$query = "(922=MIAMI), (131=2014-12-16+)";
$search = $rets->SearchQuery("Property", $class, $query, array("SystemName" => 1, 'Limit' => 1 ));
if ($rets->NumRows($search) > 0)
{
$fields_order = $rets->SearchGetFields($search);
$this_record = array();
while ($record = $rets->FetchRow($search))
{
foreach ($fields_order as $fo)
{
echo $this_record[] = $record[$fo];
}
$comma_fields_order = implode(",", $fields_order);
$comma_record = implode(",", $this_record );
echo $dfsdf = "INSERT INTO rets_property_2 (".$comma_fields_order.") VALUES (" .$comma_record.")";
dbDelta($dfsdf);
}
}
If I echo the insert query this is :
INSERT INTO rets_property_2 (sysid,1,10,11,13,14,17,19,21,22,25,28,29,30,31,39,45,47,53,54,56,57,59,61,62,63,66,69,71,73,74,75,76,80,92,93,97,98,99,100,102,106,109,110,111,113,114,115,125,126,127,128,129,131,134,136,137,143,144,149,150,157,158,160,161,164,165,167,178,180,181,188,190,193,194,195,206,207,214,223,225,226,227,229,230,232,242,245,246,247,248,250,252,261,263,264,266,267,268,274,275,283,294,295,296,314,315,319,320,321,322,324,326,327,328,329,330,331,332,333,334,335,336,337,338,341,342,347,348,351,352,353,354,355,356,360,361,362,363,364,366,367,368,369,370,372,373,374,375,376,881,886,891,893,894,922,924,1088,1218,1223,1329,1333,1335,1337,1339,1358,1410,1462,1463,1464,1465,1473,1485,1486,1487,1488,1490) VALUES (305578689,Condo/Co-Op/Villa/Townhouse,33131,,,,3003,42,None,,4,,,,Entry Level,Miami Board of Realtors,0,,Cbs Construction,,,Electric Cooling,,Miami-Dade County,,,,ASIA CONDOMINIUM,,,,,,2008-06-12T14:19:47,5,2630,,,,,2,,1,Electric Heat,Condo,9,Yes,ASIA IS BRICKELL KEY ISLAND'S PREMIER LUXURY BLDG. W/ ONLY 123 UNITS, PRIVATE ELEVATORS, SPECTACULAR VIEWS AND MUCH MORE.,,,,,3813,2014-12-23T09:16:55,EWM 09,0648464,6000000,,Daysi Morey,,1,M1242705,,No,,Vacant,EWM Realty International,305-329-7600,,Maximum 20 Lbs,Yes,,0043,,Funding,Yes,5000000,T,EXOTIC LUXURY AND STRIKING DESIGN MAKES ASIA THE # 1 RESIDENCE FOR THE MOST DISCRIMINATING OWNER. SMART TECHNOLOGY, PRIVATE ELEVATORS, FLOOR TO CEILING WINDOWS, BREATHTAKING VIEWS OF BISCAYNE BAY, BAYSIDE, MIAMI RIVER AND MIAMI;S EXHUBERTANT SKYLINE. 12' CIELINGS,MARBLE BATHROOMS, GOURMET CHEF STYLE KITCHEN, LUXE BATH WITH FRENCH VANILLA IMPORTED MARBLE AND MUCH MORE MAKES THIS REMARKABLE RESIDENCE A SANCTUARY NESTLED IN BISCAYNE BAY. ALLOW 24 HOURS NOTICE FOR SHOWINGS.,,,6,6,,,0,,2014-01-24T10:02:22,Active-Available,BRICKELL KEY BLVD.,900,,,4663,Tax Reflects City & County Tax,New Construction,,,42,,0,2007,,None,Yes,Bay Front,2008,Under Construction,Bike/Jog Path,Elevator,0,No Approvals,,,ASIA CONDOMINIUM,,No,,,,Dishwasher,Dryer,Microwave,Electric Range,Refrigerator,Other Equipment/Appliances,Open Balcony,,30,Wood Floors,,Condominium,Elevator,Foyer Entry,Other Interior Features,0,All Amenities,Building Exterior,Cable Tv,1920,365,,,1,1 Assigned Space,2 Or More Spaces,,,0,Other Restrictions,,Elevator Secure,Garage Secured,Lobby Secured,,Condo 5+ Stories,34,Other,Condo,Corner Unit,High Rise,123,,Bay,,900 BRICKELL KEY BLVD. # 3003,,,,0,Miami,Florida,,,http://instatour.propertypanorama.com/instaview/mia/M1242705,2009-02-19T16:00:26,,,,ASIA CONDO UNIT 3003,1573.564,No HOPA,,,2389,No,No,No,No,900 BRICKELL KEY BLVD. 3003,Yes,)
But nothing is being inserted in the table. Where I am wrong? Is there any other method to insert the whole row directly given by fetchrow into the table?
Please show me right direction. I think the problem is with the data type, number and varchar. Then how can I format the insert query where data is coming from the array?
I know my insert query is wrong.
If I do try this
INSERT INTO `rets_property_2` ( `sysid` , `1` )
VALUES ( 526252, 'dsfsdfsdf' )
this will work fine. But the question is How can I get the values from array if the value is string then 'somestringvalue' and if the value is integer then only integervalue and then wrapping them in a array?
$query = "(922=MIAMI), (131=2014-12-16+)";
$search = $rets->SearchQuery("Property", $class, $query, array("SystemName" => 1, 'Limit' => 5 ));
if ($rets->NumRows($search) > 0) {
$fields_order = $rets->SearchGetFields($search);
while ($record = $rets->FetchRow($search)) {
//var_dump($fields_order);
foreach ($fields_order as $fo) {
if( is_numeric($record[$fo])){
$valuesd[] = $record[$fo];
}else{
$onlyconsonants = str_replace("'", "", $record[$fo]);
$valuesd[] = "'".$onlyconsonants."'";
}
}
$comma_fields_order = "`".implode("`,`", $fields_order)."`";
$valuestring = implode(",", $valuesd );
$wpdb->query("INSERT INTO rets_property_2 (".$comma_fields_order.") VALUES (".$valuestring.")");
unset($valuesd);
$valuesd = array();
} /* end while */
} /* end if of number of row */
I would suggest using DBName column names instead of SystemName for your database table column names.
I would also suggest using PDO to prepare/execute your statements.
The below example should help you along:
<?php
$sysid = '1234'
$property_1 = '1111 main'
$stmt = $db->prepare("INSERT INTO table_name(`sysid`, `property_1`) VALUES( ?, ?)");
$stmt->execute(array($sysid, $property_1));
Related
Insert result from DOMXpath into MySQL
Im using this DOMXpath query to retrieve some columns from another page. $html = file_get_contents("http://localhost:8888/stockPrices.php"); libxml_use_internal_errors(true); $doc = new \DOMDocument(); if($doc->loadHTML($html)) { $result = new \DOMDocument(); $result->formatOutput = true; $table = $result->appendChild($result->createElement("table")); $thead = $table->appendChild($result->createElement("thead")); $tbody = $table->appendChild($result->createElement("tbody")); $table->setAttribute('class', 'table table-hover'); $xpath = new \DOMXPath($doc); $newRow = $thead->appendChild($result->createElement("tr")); foreach($xpath->query("//table[#id='kurstabell']/thead/tr/th[position()=2 or position()=3 or position()=8 or position()=9 or position()=10]") as $header) { $newRow->appendChild($result->createElement("th", trim($header->nodeValue))); } foreach($xpath->query("//table[#id='kurstabell']/tbody/tr") as $row) { $newRow = $tbody->appendChild($result->createElement("tr")); foreach($xpath->query("./td[position()=2 or position()=3 or position()=8 or position()=9 or position()=10]", $row) as $cell) { $newRow->appendChild($result->createElement("td", trim(htmlentities($cell->nodeValue)))); } } echo $result->saveXML($result->documentElement); } This generates four columns, aktier, senaste, högst, lägst and omsatt. But i dont know how to insert this to a MySQL table. Im thinking to first generate a array of the result, like: Array ( [1] => stdClass Object ( [aktie] => AAK AB [senaste] => 634,50 [högst] => 638,50 [lägst] => 622,50 [omsatt] => 32 094 048 ) [2] => stdClass Object ( [aktie] => ABB Ltd [senaste] => 162,80 [högst] => 163,30 [lägst] => 161,90 [omsatt] => 167 481 268 ) (you get the hang of it..) ) According to this image: And then loop the array into the table. Something like this? $sql = "INSERT INTO stock_list (`aktie`, `senaste`, `högst`, `lägst`, `omsatt`, `timestamp`) VALUES (:aktie, :senaste, :högst, :lägst, :omsatt)"; $query = $database->prepare($sql); foreach($data as $stock){ $query->execute(array(':aktie' => $stock->stock, ':senaste' => $stock->prevclose, ':högst' => $stock->high, ':lägst' => $stock->low, ':omsatt' => $stock->volume )); } My question: How do i populate the array with data? How do i loop the result in a mysql query?
Don't know if this is a work around. But it is currently doing what I'm asking for. // build query... $sql = "INSERT INTO stocks"; // columns to insert into... $sql .="(`name`, `closing`, `high`, `low`, `turn`, `timestamp`)"; // implode values of $array... // notice array_chunk, this functions splits a big array into multi. $str = NULL; foreach (array_chunk($a, 5) as $row) { $str .= '("'. implode('","',$row).'",NOW()),'; } // Remove last ',' (comma) from string // We added commas in the previous step $str = rtrim($str,','); $sql .= 'VALUES '. $str ; // execute query... $app = new Connection(); $query = $app->getConnection()->prepare($sql); $query->execute(); if ($query->rowCount() <= 0) { echo "Something went wrong."; return false; } return true;
My guess is that what you really want is something along the lines of: $query = 'INSERT INTO stock_list (`aktie`, `senaste`, `högst`, `lägst`, `omsatt`, `timestamp`) VALUES (:aktie, :senaste, :högst, :lägst, :omsatt, NOW())'; $stmt = $app->getConnection()->prepare($query); foreach ($data as $stock) { $stmt->execute( [ ':aktie' => $stock->aktie, ':senaste' => $stock->senaste, ':högst' => $stock->{'högst'}, ':lägst' => $stock->{'lägst'}, ':omsatt' => $stock->omsatt, ] ); $stmt->closeCursor();//might be required depending on DB driver, not for MySQL, though } Note that I call NOW() in the query string, and I don't bind that SQL function call to the parameters I execute the prepared statement with. All in all though, a timestamp field is best set by the DB itself (with a DEFAULT CURRENT_TIMESTAMP in the field definition). Then you can just leave the timestamp field out of your INSERT query, and it'll be set correctly for you. I've also changed the way you're using the objects stock. From the var_dump I can see the properties aren't called stock, high, low and all that. The problem is, some of these property names (lägst for example) are a bit dodgy. You'll probably have to access those using a string, which can be done, like I did, by writing $objVar->{'property name as string'}. If I were you, though, I'd look into ways of changing what $data actually looks like, and change the property names if at all possible.
insert an array into mysql database
I have the following array which I would like to insert into mysql database. Item[0] = Soccer Item[1] = Rugby Item[2] = Football Item[3] = Netball Item[4] = Hockey I am using the following function to insert into the database, located in functions.php: //Capture items function item($register_data) { array_walk($register_data,'array_clean'); $fields = ' '.implode(',',array_keys($register_data)).' '; $data = '\''.implode('\',\'',$register_data).'\''; //Insert user Data into the database $query = "INSERT INTO items ($fields) VALUES ($data)"; mysql_query($query); } Now this is how I insert: for($i =0;$i<4;$i++) { $item = array($i = item[i]); } //Call the function to insert into the database item($item); This method doesn't seem to work. Please assist
PHP has a built in serialize & deserialize functions (http://php.net/manual/en/function.serialize.php) for that. You can pass any object or array to it, and it will return a serialized string, which you can store in a single field in the database.
Since your items table has two columns, one of which is id (auto increment) you're going to want to skip over it and only specify the second column ItemName. This is described in the mysql documentation on this page. Lets say you want to insert 5 sports in this table: $sports[0] = "Soccer"; $sports[1] = "Rugby"; $sports[2] = "Football"; $sports[3] = "Netball"; $sports[4] = "Hockey"; You'll want the query to look something along these lines: INSERT INTO items (ItemName) VALUES ('Soccer'), ('Rugby'), ('Football'), ('Netball'), ('Hockey'); The code would look something like this: function insert($insert_data) { $fields = implode(', ', $insert_data); $data = '(\''.implode('\'), (\'', $insert_data).'\')'; //mysql_query("INSERT INTO items (ItemName) VALUES $data;"); echo "INSERT INTO items (ItemName) VALUES $data;"; } $sports = array(); $sports[0] = "Soccer"; $sports[1] = "Rugby"; $sports[2] = "Football"; $sports[3] = "Netball"; $sports[4] = "Hockey"; insert($sports); You may also want to sanitize the strings first and take a look at mysqli since mysql is pretty outdated.
PHP Alternative to using a query within a loop
I was told that it is a bad practice to use a query (select) within a loop because it slows down server performance. I have an array such as Array ( [1] => Los Angeles ) Array ( [2] =>New York) Array ( [3] => Chicago ) These are just 3 indexes. The array I'm using does not have a constant size, so sometimes it can contain as many as 20 indexes. Right now, what I'm doing is (this is not all of the code, but the basic idea) For loop query the server and select all people's names who live in "Los Angeles" Print the names out Output will look like this: Los Angeles Michael Stern David Bloomer William Rod New York Kary Mills Chicago Henry Davidson Ellie Spears I know that's a really inefficient method because it could be a lot of queries as the table gets larger later on. So my question is, is there a better, more efficient way to SELECT information based on the stuff inside an array that can be whatever size?
Use an IN query, which will grab all of the results in a single query: SELECT * FROM people WHERE town IN('LA', 'London', 'Paris')
To further add to MrCodes answer, if you start with an array:- $Cities = array(1=>'Los Angeles', 2=>'New York', 3=>'Chicago'); $query = "SELECT town, personname FROM people WHERE town IN('".implode("','", $Cities)."') ORDER BY town"; if ($sql = $mysqliconnection->prepare($query)) { $sql->execute(); $result = $sql->get_result(); $PrevCity = ''; while ($row = $result->fetch_assoc()) { if ($row['town'] != $PrevCity) { echo $row['town']."<br />"; $PrevCity = $row['town']; } echo $row['personname']."<br />"; } } As a database design issue, you probably should have the town names in a separate table and the table for the person contains the id of the town rather than the actual town name (makes validation easier, faster and with the validation less likely to miss records because someone has mistyped their home town)
As #MrCode mentions, you can use MySQL's IN() operator to fetch records for all of the desired cities in one go, but if you then sort your results primarily by city you can loop over the resultset keeping track of the last city seen and outputting the new city when it is first encountered. Using PDO, together with MySQL's FIELD() function to ensure that the resultset is in the same order as your original array (if you don't care about that, you could simply do ORDER BY city, which would be a lot more efficient, especially with a suitable index on the city column): $arr = ['Los Angeles', 'New York', 'Chicago']; $placeholders = rtrim(str_repeat('?, ', count($arr)), ', '); $dbh = new PDO("mysql:dbname=$dbname", $username, $password); $qry = $dbh->prepare(" SELECT city, name FROM my_table WHERE city IN ($placeholders) ORDER BY FIELD(city, $placeholders) "); if ($qry->execute(array_merge($arr, $arr))) { // output headers echo '<ul>'; $row = $qry->fetch(); while ($row) { $current_city = $row['city']; // output $current_city initialisation echo '<li>'.htmlentities($current_city).'</li><ul>'; do { // output name $row echo '<li>'.htmlentities($row['name']).'</li>'; } while ($row = $qry->fetch() and $row['city'] == $current_city); // output $current_city termination echo '</ul>'; } // output footers echo '</ul>'; }
That's the purpose of prepared statements. You bind a placeholder to a value, and use it like a variable, with the same query. Since the query hasn't changed, you minimize the communication with the mysql server, resulting in an efficiency boost. Example using PDO: $cities = array( "Los Angeles", "New York", "Chicago" ); try { //Change database parameters here (user, pass, database name) $db = new PDO("mysql:host=localhost;dbname=users", "user", "pass"); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $stmt = $db->prepare("SELECT * FROM `users` WHERE `city` = :city"); foreach ($cities as $city) { $stmt->bindValue(":city", $city); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); //Output data here. You can format it however you'd like var_dump($city, $result); } } catch (PDOException $e) { //Error handling here }
Insert if not exists in DB and delete if not in an array
I have an array like this : $services = array( array("id" => "1", "desc" => "desc 1"), array("id" => "2", "desc" => "desc 2" ), ...... ); I want to insert those services in TABLE_SERVICE . each service is inserted if it doesnt exists in TABLE_SERVICE , and deleted it if it exists in TABLE_SERVICE but not in $services array. I could just delete all records in TABLE_SERVICE and then insert all $services elements , but that can be an issue with performance because i often have large set of data in both TABLE_SERVICE and $services . So is there an efficient way to do this ? Thanks.
If it was me I'd iterate over $services collecting ids: $ids = array(); foreach($services as $service) { $ids[] = $service['id']; } Then using PHP's join and the select NOT IN "DELETE FROM TABLE_SERVICE WHERE id NOT IN (" . join($ids,',') . ")" After that, iterate over the array again to insert/update using ON DUPLICATE KEY "INSERT INTO TABLE_SERVICE (id,desc) VALUES (?,?) ON DUPLICATE KEY UPDATE desc = ?" Since oracle doesn't have ON DUPLICATE KEY this stackoverflow question might help you with that last part.
My answer would be that there isn't really an efficient way to do this. I have thought about a merge, but to be efficient, you would still be better off first inserting it in a temporary table. Then you might as well just truncate table_service and then fill it again from your $service array. Even if Kristoffer's anwser could work, it might still be slower than a truncate insert. This is my php method to quickly insert a lot of records: The advantage of this is, that your insert statement will be parsed only once instead for each insert, which will improve the speed greatly. Sometimes by a factor 100 or so. $connection = oci_connect(<YOUR CONNECTION>); $sql = insert into table_service (id, var) values (:id, :var); // desc is a reserved word, cannot be a column name $parsed = oci_parse($connection, $sql); $binds = array(':id', ':var'); $sizes = array(6, 20); $data = $services; $errors = execute_multiple($binds, $sizes, $data); if ($errors > 0) // log or show else // feedback: full succes! function execute_multiple($binds, $sizes, $data, $commit = true) { $errorCount = 0; // first determine all binds once foreach ($binds as $i => $bind) { // ${trim($bind, ':')} example: :some_id -> $some_id oci_bind_by_name($parsed, $bind, ${trim($bind, ':')}, $sizes[$i]); } // Then loop over all rows and give the variables the new value for that row // This is because the variables remain binded! for ($row=0; $row<count($data); $row++) { foreach ($binds as $i => $bind) { $value = array_key_exists($i, $data[$row]) ? substr($data[$row][$i], 0, $sizes[$i]) : null; ${trim($bind, ':')} = trim($value); } if (! #oci_execute($this->parsed, OCI_DEFAULT)) // don't auto commit $errorCount++; } if ($commit) oci_commit($connection); return $errorCount; }
How do I select a cell with multiple values in one column?
I have an MYSQL table with a large product list. In this product list table there are categories, a name, description, text, etc. I want to add a modifier for the industries that it can be used in (e.g. hospitals, schools, events, sport events, etc.) I'm running this query through PHP/MYSQL right now: public function GetIndustrySeries($identifier, $SeriesIDArray = null) { $query = "select ser.Identifier, ser.ModelNumber, ser.Title, ser.Caption, ser.Description, ser.Picture, ser.Industry, cat.TitleText, ser.AutoID, ser.BasePrice from ProductSeries ser inner join ProductIndustry cat on cat.Industry = ser.Industry where ser.Industry like ?"; if($SeriesIDArray != null && count($SeriesIDArray) > 0) $query .= " and "; $i = count($SeriesIDArray); $parameters = array(); $parameters[0] = "s"; $parameters[1] = $identifier; if($SeriesIDArray != null){ foreach($SeriesIDArray as $id) { $parameters[0] .= "i"; array_push($parameters, $id); $query .= " ser.AutoID = ?"; if($i > 1) $query .= " or "; $i--; } } $stmt = $this->_mysqli->prepare($query); //$stmt->bind_param('ss', $identifier); call_user_func_array(array($stmt,'bind_param'), $parameters); $stmt->execute(); $stmt->bind_result($ident2, $model, $title, $caption, $description, $picture, $ident, $catText, $sid, $price); $stmt->store_result(); if($stmt->num_rows < 1) { $stmt->close(); return null; } $array = array(); while($stmt->fetch()) { array_push($array, array('seriesLink' => "/products/$ident2/$model", 'seriesTitle' => $title, 'seriesImage' => $picture, 'seriesCaption' => $caption, 'seriesDescription' => $description, "seriesCategoryName" => $catText, "seriesID" => $sid, "basePrice" => $price)); } $stmt->close(); return $array; } I've tried using the % modifier in that code on both sides of the ? but I'm getting an error down the line: Warning: call_user_func_array() [function.call-user-func-array]: First argument is expected to be a valid callback, 'Array' was given in C:\wamp\www\database.php on line 70. In the table I have a column for "Industry" and what I want to do is put the industries that the product qualifies for in there hoping it can accept multiple values: "school,hotel,hospital"
You are using the wrong method to get the data. call_user_func calls a method (see http://au.php.net/call_user_func). You want to query the data using mysql functions (http://au.php.net/manual/en/book.mysql.php), PDO (http://au.php.net/manual/en/book.pdo.php) or a data abstraction layer such as zend_db, doctrine, etc.
Would seem to me to be a lot easier just to loop through the array of industries wanted and rather than doing a 'LIKE' doing $i=0 $query...... ....WHERE ( ser.Industry = '".$industry(i)."'"; i++; while $industry(i) { $query.=" OR ser.Industry = '".$industry(i)."'"; i++; } $query.=")"; Re-reading your question however it seems you need an intermediate table with a two part key, column 1 would be the industry and column two the product, you would then have the key for the product and the key for the industry and all you would need to do is select the rows from your category table where there was a record in the new table with the indusrty you were seeking, or all the rows from the new table which had the category from the first table to see all industries the category fitted, or all rows from the new table for an industry to see all categories that matched. It seems you could do with more tables since category looks like one table, industry another and product yet another another. Remember the first rule, the data should be dependent on the key, the whole key and nothing but the key. Hope this helps. SteveK
It was a combination of my tables not having the same values under the Industry as well as the $identifier part in $paramters[1]; Also some I had to modify some parts of the query string. Thanks for your help