Creating a database query using dsql - php

Is it possible to make a query using any of the methods of dsql() ?
something like:
$dq=$this->api->db->dsql()->execute('insert into table xx (field1,field2) values ('a','b')');
Thanks

DSQL is now refactored as a Separate Library: https://git.io/dsql
$this->api->db->dsql()->table('table')->set('field1','a')->set('field2','b')->do_insert();
Naturally you can also use
$this->api->db->dsql()->table('table')->set($associative_array)->do_insert();

Romans already showed an example of an insert. You can select an array of data like this (note the debug() is optional and will output the resulting sql statement at top of the page)
$db=$this->api->db->dsql()->table('table1 x')
->field('x.col1')
->field('sum(x.col2) col2')
// ->debug()
->join('table2 y','x.id=y.some_id')
->where('x.col3','Y')
->where('x.col4',$this->auth->api->get('id'))
->group('x.col2')
->order('x.col1')
->do_getAll();
and then loop through the result set to do something
foreach ($db as $row) {
if (is_array($row)) {
//do something here with row['col1'], row['col2']
}
}
just select a single value
$db=$this->api->db->dsql()->table('table1 x')
->field('x.col1')
->where('x.col2,'constant')
->do_getOne();
You can update records
$this->api->db->dsql()->table('table1 x')
->where('id',$somevariable)
->set('col1',$somevalue)
->debug()
->do_update();
and delete records
$this->api->db->dsql()->table('table1 x')
->where('id',$somevariable)
->do_delete();
Where possible, it's best to use models like below to persist your data but the nice thing about ATK4 is it doesnt get in the way so if you need to, you can execute SQL anywhere in your page to achieve a simple result.
$s=$p->add('Model_Story')->loadData($story);
$s->set('points', $value);
$s->update();

Related

Codeigniter Commands out of sync; you can't run this command now

I've been spent hours trying to figure out how I'm supposed to get around this error in my scenario. I'm trying to run a few queries in sequence.
I have read: codeigniter : Commands out of sync; you can't run this command now, however I am not able to update /system/database/drivers/mysqli/mysqli_result.php
I've tried:
$this->db->reset_query();
$this->db->close();
$this->db->initialize();
$this->db->reconnect();
mysqli_next_result( $this->db->conn_id );
$query->free_result();
But they either give me the same error, or different errors which I will detail in the comments of my code.
The way my code is organized- I have a make_query method that takes a bunch of search options and figures out which tables to join and fields to search based on those. Sometimes, I just want to count results, sometimes I want all of the resulting data, sometimes I just want distinct values for certain fields or to group by certain fields. So I call make_query with my options, and then decide what to select afterwards. I have also been saving my query text to report, so that users can see what query is being run.
One interesting thing I have noted is that when I have no options set (ie there are no WHERE clauses in my SQL), I do not get this error and the multiple queries are able to run with no problem!
Here is my code:
//Get rows from tblPlots based on criteria set in options array
public function get_plot_data($options=array()){
$this->db->save_queries = TRUE;
log_message('debug','before make query 1 get plot data');
$this->make_query($options,'plot');
log_message('debug','after make query 1 get plot data');
$this->db->distinct();
//Now, set select to return only requested fields
if (!empty($options['fields']) and $options['fields']!="all" ){
//Because other tables could be joined, add table name to each select
array_walk($options['fields'], function(&$value, $key) { $value = 'tblPlots.'.$value;} );
$this->db->select($options['fields']);
}
if (!empty($options['limit']) and $options['limit']>0){
$this->db->limit($options['limit'], $options['offset']);
}
//Get the resulting data
$result=$this->db->get('tblProgram')->result();
$query_text = $this->db->last_query(); //tried removing this but didn't help
log_message('debug','query text '.$query_text);
$this->db->save_queries = FALSE;
//get the number of rows
//$this->db->reset_query();
//$this->db->close();
//$this->db->initialize();
//$this->db->reconnect();
//mysqli_next_result( $this->db->conn_id );
//$this->db->free_result(); //Call to undefined method CI_DB_mysqli_driver::free_result()
//$result->free_result(); //Call to a member function free_result() on array
log_message('debug','before make query 2');
$this->make_query($options,"plot");
$this->db->select('pkProgramID');
log_message('debug','before count results');
//this is where my code errors out trying to do the next step:
$count=$this->db->count_all_results('tblProgram');
}
I'm not including the code for make_query because it is long and calls other functions, but it runs successfully the first time and outputs the SQL query I would expect. If it would be helpful, I can include that code as well.
I'm not sure how to correctly call free_result() given that the CI documentation only gives an example using query('SQL QUERY') and I am building the query using Active Record, so I'm not sure how to use free result in my scenario? Maybe that's the issue?
$query2 = $this->db->query('SELECT name FROM some_table');
$query2->free_result();
Thank you for any help!
I ended up posting on a CI forum that suggested https://www.youtube.com/watch?v=yPiBhg6r5B0 which worked! Also I ended up having to join my tables differently to avoid timeouts (I think I was having trouble because I was using AJAX to call many queries asynchronously and one of them was timing out). Hope this helps someone!

What's the best way to retrieve data from a database and pass it as variables

So I have done some searching but the results seems to be kind of scrambled, that's why I'm asking here.
The problem is that I have a setup.php file, in which I preload the options that are needed to load some things in the page, and I don't know if this is the best method.
Here is the code:
function fetch_site_option($id){
$conn=Core::getInstance()->db->prepare("SELECT value FROM options WHERE id = ?");
$conn->bindParam(1,$id,PDO::PARAM_INT);
$conn->execute();
if($conn->rowCount()==1){
$data=$conn->fetch(PDO::FETCH_ASSOC);
}else{
$data=null;
}
return $data['value'];
}
and the values that need to be retrieved:
$siteTitle=fetch_site_option('1');
$mainPage=fetch_site_option('2');
$debug=fetch_site_option('3');
$logo=fetch_site_option('4');
$sTT=fetch_site_option('5');
This repeats a lot of times, and that's why it needs to be very efficient.
Thanks in advance.
To be more efficient, you should try to merge your multiple requests into one. Try something like this:
SELECT id, value FROM options WHERE id IN (?,?,?,?,?)
This will return all required rows in one request. Instead of returning one value at a time, you should change the function fetch_site_option() to return an array of ids and values.

php querying for data just inserted...by itself

I don't know how to title this...but anyway,
In my script if data doesn't exist, i insert a new row into a database and then check again for that row, for example:
1 search the db
2 if nothing
include(create.php) -> create entry
3 search the db for that row
Am I going to have to put in a usleep(1000000); between the include and the next search on the db? or is there something I am missing?
THanks!
Include the file create.php on top of your php script and call the functions you required inside this block
if ($number_of_rows < 1) { //call the functions from create.php you need here}
Seriously, why even have a create.php used in that manner anyway? Include create.php at the top of the page, put all the insert syntax into a function, and call it later on in your main script. That would work.
Or even better, don't even bother including it. Just run the queries straight in your main page. That way if you need to change something, you won't have to affect other pages.
You can use something like that
$query="Select * from table where id='23'";
$result=mysql_query($query);
if(mysql_num_rows($result)>0){
//result find in sql table
}else{
$query1="INSERT INTO table (schema) values(values)";
$result=mysql_query($query1);
}
sleep(1);
$query="select *...."
You can also use mysql INTERVAL query.It will automatic make a query after a particular interval and search for data.

Search with PHP/MySQL and dynamically update with jQuery

I was wondering how to do the following best with PHP/MySQL and jQuery:
There is a basic search mask where you enter a city and a from-to-date. You process to the search-result page, where you then can narrow your search results with certain parameters (checkboxes, jQuery slider, text-input, ...). The search-results should then update on the fly without the whole page being reloaded...
I manage to use jQuery ajax and load to send information to another php file, perform e.g. a SELECT and return the results to the search detail page, but I don't know how to combine different changes that narrow the search results.
Furthermore, there are already results on the detail page, so I do not need to add more results but "delete" the results that do not fit anymore...
The thing is that each parameter to narrow the search is connected to another table in the database. Do I have to and how do I add joins to the original query...? Or am I thinking in the wrong direction?
Yes, this is absolutely the right direction. Use
$(document).ready(function() {
$('#ID_OF_YOUR_ELEMENT_TO_LOAD_INTO').load("load.php?parameter1=<?php echo $parameter1; ?>&parameter2=<?php echo $parameter2; ?>");
});
to get the results when the user gets on the page for the first time, to get the results according to your city and your dates.
Check in the load.php which parameters are set and use the ones that are set to build your query. Then, when the form (or forms, depending) are updated, you have to use .load again, like this:
$('#ID_OF_YOUR_FORM_BEING_UPDATED').change(function() {
$('#ID_OF_YOUR_ELEMENT_TO_LOAD_INTO').load("load.php?parameter1=<?php echo $parameter1; ?>&parameter2=<?php echo $parameter2; ?>&parameter3=<?php echo $parameter3; ?>");
});
Get the initial tuples via PHP/MySQL, save them into some Javascript structure and create the html needed to display the data with javascript from this structure.
Any time you want to filter the data you rewrite the html and check the filter condition on the fly, e.g. don't write tuples from the structure that don't match your filter condition.
You can see who this is done at http://www.wowhead.com
This is of course just one way. ;-)
You could always write some code to generate an SQL query based on passed arguments.
You ajax could query the page with a bunch of arguments in addition to your basic city and from-to date based on what the user has selected. If your page preserves the previous search options selected, it should be able to just let the user add on more options and keep processing them in the same way. Your php would then test to see if the arguments are set in the $_POST or $_GET variable ($_POST is more secure for ajax generally, but my example will use $_GET for simplicity) and build the query like that.
Example:
Javascript generates a query like searchAjaxHandler.php?city=Chicago&from=2012-03-01&to=2012-03-05&someColumnLowerRange=500&someColumnUpperRange=700
Your php script then processes as follows:
$query = "SELECT * FROM Data WHERE City=? AND Date > ? AND Date < ?";
$arguments = array($_GET['city'], $_GET['from'], $_GET['to']);
if (isset($_GET['someColumnLowerRange'])) {
$query .= " AND someColumn > ?";
$arguments[] = $_GET['someColumnLowerRange'];
}
if (isset($_GET['someColumnUpperRange'])) {
$query .= " AND someColumn < ?";
$arguments[] = $_GET['someColumnUpperRange'];
}
//execute the query
//using PDOs (google them...they are a good way to prevent sql injection and
//support multiple database types without modifying code too much), create a
//statement with the above query in put the statement in $statement
$statement->execute($arguments); //this uses the $arguments array to fill in the prepared statement's ?'s
//then do the stuff to get the retrieved rows out of the result returned
After all that, the javascript side would just to the same thing you were doing before by replacing all the previous results with the results that you got back.

PHP IF statement not taking variable into account!

I have a tabled view in a while loop, where a user can view information on books.
For example, book ISBN, book name, read status...
Basically, when the user sets their 'readstatus' to 'complete' I want that specific table row to become grey! The logic is very straight forward, however I can't get my IF statement to recognise this:
if ($readstatus == 'complete') {
echo '<tr class="completed">';
}
else if ($readstatus != 'complete') {
echo '<tr class="reading">';
}
I'm obviously doing something wrong here, table content to change if the value of 'readstatus' = 'complete', if not, then output is the default
Why are you using $_GET? Does this information come from an HTML form or a URL etc... ?
I suspect you meant to change $readstatus = $_GET['readstatus']; to $readstatus = $row['readstatus'];.
$_GET is an aray of GET parameters which come from the query string.
$row is a row in your database, so if the information is in the database - which I suspect it is - you want to use $row instead of $_GET.
Try changing $readstatus = $_GET['readstatus']; to $readstatus = $row['readstatus'];
The $_GET function relies on the value being contained in the query string of the URL, and it has nothing to do with the database. I have a hunch you're trying to get the value from the database here and you're using the wrong function to do it.
$_GET['readstatus'] says the value is coming from the browser.
$row['readstatus'] says the value is coming from the database.
You need to decide which should take precedence-- probably the $_GET['readstatus']` because it's what the user wants to change. If that's the case, you need to update your database with the new readstatus before you requery the db for the dataset.

Categories