SQL query result to string - php

I'm using SQL in Yii framework.
I need to show the person's latest active week (it's number and date).So I wrote following code:
public function latestWeek()
{
$datalogin=//the login is working fine
$sql ="SELECT w.number,MAX(w.start_date)
FROM tbl_person_week t, tbl_week w
WHERE t.person_id=$this->id AND t.week_id=w.id";
$query = mysqli_query($datalogin, $sql);
return $query;
}
Now , I checked this query on the server and it works fine (almost) but first thing: I need to convert it into string , because yii's CgridView can't read it , and I couldn't find a working solution for this.
Second: on the server , it gave me the max date indeed , but not it's correct number , but the first number available. How can I fix this as well?

Queries like that should never be used in objective framework. If yu want to execute your own query, you should do it this way:
$sql = "your sql code";
$array = Yii::app()->db->createCommand($sql)->queryAll();
As result you will get multidimensional array with selected columns and rows
If you want to use it in grid view, you should do it this way:
$count = Yii::app()->db->createCommand($sql)->queryScalar();
$dataProvider = new CSqlDataProvider($sql, array('totalItemCount'=>$count));
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'grid-id',
'dataProvider'=> $dataProvider,
));
You can also use connection other than Yii::app()->db. Check CDbConnection class in docs.
edit: if you wanna use queries like mysql_fetch_assoc, check out also queryRow() method instead of queryAll()

Use Mysql_fetch _array
public function latestWeek()
{
$datalogin=//the login is working fine
$sql ="SELECT w.number,MAX(w.start_date)
FROM tbl_person_week t, tbl_week w
WHERE t.person_id=$this->id AND t.week_id=w.id";
$query = mysqli_query($datalogin, $sql);
while($row = mysqli_fetch_array($query)){
echo $row;
}
}

Assuming from your qu. that you want the week number and start date as one string, you have to concatenate the two columns in the sql.
You also need to specify that the week number is from the row with the maximum start date, which isn't as simple as you might first think.
I don't like injecting the person_id straight into SQL, it isn't awful in this case but is a bad habit to get into security-wise. There are binding methods available in the framework and I agree with Arek, that you should lean on the yii framework as much as possible.
To get the scalar string value, if you are insisting on using your own SQL.. I suggest the following:
$sql='
SELECT CONCAT('Week ',tw.number,' starting ',tw.start_date)
FROM tbl_week tw
JOIN (
SELECT MAX(twi.start_date) max_start_date
FROM tbl_week twi
JOIN tbl_person_week tpwi
ON tpwi.week_id = twi.id
AND tpwi.person_id = :person_id
) i
ON tw.start_date = i.max_start_date;
';
$command=Yii::app()->db->createCommand($sql);
$command->bindParam(":person_id", $this->id);
return $command->queryScalar();

Related

Trying to create and echo array via pg_query_params

I've worked with Postgresql some, but I'm still a novice. I usually default to creating way too many queries and hacking my way through to get the result I need from a query. This time I'd like to write some more streamlined code since I'll be dealing with a large database, and the code needs to be as concise as possible.
So I have a lot of point data, and then I have many counties. I have two tables, "counties" and "ltg_data" (the many points). My goal is to read through a specified number of counties (as given in an array) and determine how many points fall in each county. My novice, repetitive and inefficient way of doing this is by writing queries like this:
$klamath_40_days = pg_query($conn, "SELECT countyname, time from counties, ltg_data where st_contains(counties.the_geom, ltg_data.ltg_geom) and countyname");
$klamath_rows = pg_num_rows($klamath_40_days);
If I run a separate query like the above for each county, it gives me nice output, but it's repetitive and inefficient. I'd much rather use a loop. And eventually I'll need to pass params into the query via the URL. When I try to run a for loop in PHP, I get errors saying "query failed: ERROR: column "jackson" does not exist", etc. Here's the loop:
$counties = array ('Jackson', 'Klamath');
foreach ($counties as $i) {
echo "$i<br>";
$jackson_24 = pg_query($conn, "SELECT countyname, time from counties, ltg_data where st_contains(counties.the_geom, ltg_data.ltg_geom) and countyname = ".$i." and time >= (NOW() - '40 DAY'::INTERVAL)");
$jackson_rows = pg_num_rows($result);
}
echo "$jackson_rows";
So then I researched the pg_query_params feature in PHP, and I thought this would help. But I run this script:
$counties = array('Jackson', 'Josephine', 'Curry', 'Siskiyou', 'Modoc', 'Coos', 'Douglas', 'Klamath', 'Lake');
$query = "SELECT countyname, time from counties, ltg_data where st_contains(counties.the_geom, ltg_data.ltg_geom) and countyname = $1 and time >= (NOW() - '40 DAY'::INTERVAL)";
$result = pg_query_params($conn, $query, $counties);
And I get this error: Query failed: ERROR: bind message supplies 9 parameters, but prepared statement "" requires 1 in
So I'm basically wondering what the best way to pass parameters (either individual from perhaps a URL passed param or multiple elements in an array) to a postgresql query is? And then I'd like to echo out the summary results in an organized manner.
Thanks for any help with this.
If you just need to know how many points fall into each county specified in an array, then you can do the following in a single call to the database:
SELECT countyname, count(*)
FROM counties
JOIN ltg_data ON ST_contains(counties.the_geom, ltg_data.ltg_geom)
WHERE countyname = ANY ($counties)
AND time >= now() - interval '40 days'
GROUP BY countyname;
This is much more efficient than making individual calls and you return only a single instance of the county name, rather than one for every record that is retrieved. If you have, say 1,000 points in the country Klamath, you return the string "Klamath" just once, instead of 1,000 times. Also, php doesn't have to count the length of the query result. All in all much cleaner and faster.
Note also the JOIN syntax in combination with the PostGIS function call.
To execute a query with a parameter in a loop for several values you can use the following pattern:
$counties = array('Jackson', 'Josephine', 'Curry');
$query = "SELECT countyname, time from counties where countyname = $1";
foreach ($counties as $county) {
$result = pg_query_params($conn, $query, array($county));
$row = pg_fetch_row($result);
echo "$row[0] $row[1] \n";
}
Note that the third parameter of pg_query_params() is an array, hence you must put array($county) even though there is only one parameter.
You can also execute one query with an array as parameter.
In this case you should use postgres syntax for an array and pass it to the query as a text variable.
$counties = "array['Jackson', 'Josephine', 'Curry']";
$query = "SELECT countyname, time from counties where countyname = any ($counties)";
echo "$query\n\n";
$result = pg_query($conn, $query);
while ($row = pg_fetch_row($result)) {
echo "$row[0] $row[1] \n";
}

Sql string query not working

I'm building some Sql queries in Yii framework.
So far all is working fine up until I need to compare a variable to a string.
Here is my function with the query:
public function countCanceled()
{
$week = Person_Event::model()->weekByDate();
$week_id = $week->id;
$datalogin = mysqli_connect( /*connect is working fine*/);
$sql = "SELECT id FROM tbl_event WHERE week_id=$week_id AND status_id='canceled'";
$query = mysqli_query($datalogin, $sql);
$numrows = mysqli_num_rows($query);
return $numrows;
}
Now , I clearly have one event with canceled status, and I ran the same query in MySql server and the result of 1 was given, so why in Yii it doesn't work?
(tried to switch "=" with "like" , made no difference)
p.s Yes , in this particular case I could use the built in Yii's queries , but I have other, much more complicated queries where I need to compare string.
Thanks,
Mark.
What is type of status_id if is char then data is space padded to full length. You can change it to varchar and then compare. And for like you can use LIKE 'canceled%'
ps. sorry I not have enough reputation to comment...:(
Best regards,
Nebojsa

echo full joomla query (with limit etc)?

I was wondering if there was a way to echo out the full query with limit and limitstart etc. I can echo out the line $query, but i want to see why the limit isn't working and I can't seem to get it to display the actual query that it's sending to the database.. Here's the code:
$params =& JComponentHelper::getParams('com_news');
$limit = $params->get('x_items', 5);
$limitstart = JRequest::getVar('limitstart', 0);
$query = "SELECT * FROM #__news WHERE published = 1 AND catid = ".$Itemid." ORDER BY date DESC";
$db->setQuery($query, $limitstart, $limit);
$rows = $db->loadObjectList();
$db->getQuery($query, $limitstart, $limit); is only displaying "SELECT * FROM jos_news WHERE published = 1 AND catid = 8 ORDER BY date DESC" which doesnt have the LIMIT params on the end of the query..
Any help would be appreciated :)
The JDatabaseQuery object has a __toString() function that outputs the query so you can do:
echo $db->getQuery();
Or if you want to pass it to a function you can explicitly cast it to a string first:
var_dump((string)$db->getQuery());
var_dump($db);die;
Do that after the loadObjectList() call. Inside the $db variable there must be a _sql attribute that is the last query executed.
Agreed with the previous answers, but... In case you are developing your own components, since I often want to know for sure what exactly is executed too, here's a simple solution:
In your models put:
$db = JFactory::getDBO();
echo $db->getQuery();
Where you want to know the query... Don't put it in (for example) your view, since it might have loaded some other dropdown list by way of execution in the meantime...
For example:
For a list-view put it right before the foreach ($items... in the public function getItems() of the model.
In a form-/item-view put it right before the return $data / return $item in the protected function loadFormData() / public function getItem($pk = null)
Hope this helps...
On new joomla versions, you need to echo __toString() on query object.
echo $query->__toString();
I get this info on this joomla answer.
Hope this helps
Joomla provides $query->dump(). To add convenience, I like to wrap it in enqueueMessage() so that the presented string is at the top of the webpage.
JFactory::getApplication()->enqueueMessage(
$query->dump(),
'notice'
);
IMPORTANT: You should never show the raw SQL string or a raw query error string to the public.
See some of my implementations at Joomla Stack Exchange.

Trying to write a PHP function for mysql, SELECT SUM()

I am trying to write a PHP function which gets the sum of values in 1 column of a table. MY SQL statement works just fine. However, when I write my function and attempt to echo the variable into my HTML code, it returns '0'.
Here is my function:
function get_asset_value($org_ID) {
global $db;
$query = "SELECT SUM(asset_value) FROM assets
WHERE org_ID = '$org_ID'";
$asset_sum = $db->query($query);
$asset_sum = $asset_sum->fetch();
return $asset_sum;
In my HTML, I have the following:
<?php echo $asset_sum; ?>
I'm not sure if this has to do with the "fetch" portion of my function. I really don't know what fetch does but I tried copying/modifying this piece of code from a working function (which doesn't return the sum, but it is a select statement).
Thank you!
In addition to
SELECT SUM(asset_value) AS the_sum FROM assets WHERE ord_ID = '$ord_ID';
...
return $asset_sum['the_sum']
by Brad,
you better do
$safer = mysql_real_escape_string($org_ID);
then do,
SELECT SUM(asset_value) AS the_sum FROM assets WHERE ord_ID = '$safer';
...
return $asset_sum['the_sum']
SELECT SUM(asset_value) AS the_sum FROM assets WHERE ord_ID = '$ord_ID';
...
return $asset_sum['the_sum'];
The issue is, you are returning an entire record, rather than just the field you want.
Also, judging by the way you are inserting that ID in your query, I suspect you are open to SQL injection. You should really learn to do prepared queries with PDO.

MYSQL syntax error

HI everyone i tried for 3 days and i'm not able to solve this problem. This is the codes and i have went through it again and again but i found no errors. I tried at a blank page and it worked but when i put it inside the calendar it has the syntax error. Thanks a million for whoever who can assist.
/** QUERY THE DATABASE FOR AN ENTRY FOR THIS DAY !! IF MATCHES FOUND, PRINT THEM !! **/
$testquery = mysql_query("SELECT orgid FROM sub WHERE userid='$userid'");
while($row4 = mysql_fetch_assoc($testquery))
{
$org = $row4['orgid'];
echo "$org<br>";
$test2 = mysql_query("SELECT nameevent FROM event WHERE `userid`=$org AND EXTRACT(YEAR FROM startdate)='2010' AND EXTRACT(MONTH FROM startdate)='08' AND EXTRACT(DAY FROM startdate)='15'") or die(mysql_error());
while($row5=mysql_fetch_assoc($test2))
{
$namethis = $row5['nameevent'];
$calendar.=$namethis;
}
}
First question: what calendar are you talking about?
And here are my 2-cents: does the EXTRACT function returns a string or a number?
Are the "backticks" (userid) really in your query? Try to strip them off.
Bye!
It's a guess, given that you haven't provided the error message you're seeing, but I imagine that userid is a text field and so the value $org in the WHERE clause needs quotes around it. I say this as the commented out testquery has quotes around the userid field, although I appreciate that it works on a different table. Anyway try this:
SELECT nameevent FROM event WHERE userid='$org' AND EXTRACT(YEAR FROM startdate)='2010' AND EXTRACT(MONTH FROM startdate)='08' AND EXTRACT(DAY FROM startdate)='15'
In such cases it's often useful to echo the sql statement and run it using a database client
First step in debugging problems like this, is to print out the acutal statement you are running. I don't know PHP, but can you first build up the SQL and then print it before calling mysql_query()?
EXTRACT() returns a number not a character value, so you don't need the single quotes when comparing EXTRACT(YEAR FROM startdate) = 2010, but I doubt that this would throw an error (unlike in other databases) but there might be a system configuration that does this.
Another thing that looks a bit strange by just looking at the names of your columns/variables: you are first retrieving a column orgid from the user table. But you compare that to the userid column in the event table. Shouldn't you also be using $userid to retrieve from the event table?
Also in the first query you are putting single quotes around $userid while you are not doing that for the userid column in the event table. Is userid a number or a string? Numbers don't need single quotes.
Any of the mysql_* functions can fail. You have to test all the return values and if one of them indicates an error (usually when the function returns false) your script has to handle it somehow.
E.g. in your query
mysql_query("SELECT orgid FROM sub WHERE userid='$userid'")
you mix a parameter into the sql statement. Have you assured that this value (the value of $userid) is secure for this purpose? see http://en.wikipedia.org/wiki/SQL_injection
You can use a JOIN statement two combine your two sql queryies into one.
see also:
http://docs.php.net/mysql_error
http://docs.php.net/mysql_real_escape_string
http://www.w3schools.com/sql/sql_join.asp
Example of rudimentary error handling:
$mysql = mysql_connect('Fill in', 'the correct', 'values here');
if ( !$mysql ) { // some went wrong, error hanlding here
echo 'connection failed. ', mysql_error();
return;
}
$result = mysql_select_db('dbname', $mysql);
if (!$result ) {
echo 'select_db failed. ', mysql_error($mysql);
return;
}
// Is it safe to use $userid as a parmeter within an sql statement?
// see http://docs.php.net/mysql_real_escape_string
$sql = "SELECT orgid FROM sub WHERE userid='$userid'";
$testquery = mysql_query($sql, $mysql);
if (!$testquery ) {
echo 'query failed. ', mysql_error($mysql), "<br />\n";
echo 'query=<pre>', $sql, '</pre>';
return;
}

Categories