I wrote a website using Google App Engine intended for the 'Datastore' database but now the website is already complete and because of Google's resources limit the website goes down too frequently (and I don't have any money to spend on it, even if I did I wouldn't :/)
Question:
When ever I fetch a table, I want to simply return it like this:
Each row is in it's own array to make it easy to iterate through
Instead of the standard number, each key would be the name of column is from
Problem:
No matter if I use fetch_all, fetch_assoc, or fetch_objectI never get anything that looks like what I am trying to get.
I am pretty bad with iterations and for loops so I couldn't figure how to do it manually.
The simplest way to build an associative array of database rows with mysqli_* is to do this:
$mysqli_query = mysqli_query($db_link, "SELECT * FROM tablename");
$result = array();
while($result[] = $mysqli_query->mysqli_fetch_assoc());
and $result will hold the array you want
Related
Basically I have coded a PHP script to pull information from a JSON file and store it all in one column inside of my MySQL database, here is the format upon which I am storing the data.
(37.50!03:37:42pm PST)
So i basically have multiple entries of similar results stored inside brackets inside of one column.
Now i want limit the results displayed when i pull that information back from the database and display it on my webpage and i cant figure out how? Is there a simple way?
I have tried using LIMIT in my SQL statement but to my understanding(maybe i am wrong) that is used for limiting the number of rows returned and not used for one unique column.
Thank you for your time.
Honestly, it might be easier to accomplish this using PHP. You haven't posted the details of what the multiple data looks like but guessing it is something like this '(37.50!03:37:42pm PST),(37.50!03:37:42pm PST),(37.50!03:37:42pm PST)'.
When fetching the data you split the data and turn it into an array and with preg_split you can have it only return you a limited number of the split array (in the example it uses 50). Post a comment if this doesn't work or if you are able to clarify the format of what multiple entries looks like in the field.
Example:
$rs = mysqli_query($conn, "SELECT yourColumn FROM your_table order by write_here_your_dec_name desc, your_desc_name");
while ($row=mysqli_fetch_assoc($rs)) {
$parts = preg_split('~,~', $row['yourColumn'], 50, PREG_SPLIT_NO_EMPTY);
foreach ($parts as $part ) {
echo "$part<br>";
}
}
I'm using CakePHP 2.1.3. I have a performance problem of looping a large set of array data returned from find('all'). I want to retrieve a query result row by row to eliminate this expensive array processing. I don't want the result set of array returning from find() or query(). What I'm trying to do is like below:
$db = $this->Model->getDataSource();
$sql = 'SELECT * FROM my_table';
if($result = $db->execute($sql){
$db->resultSet($result);
while($row = $db->fetchResult()){
// do something with $row
}
}
However, I don't want to write the raw query. Is there any Cake function that just builds the query according to the association set and executes it without returning the result set?
[Edit]
I'm currently implementing the above script in controller. My model has no associations and so I don't need to use recursive = -1. It is the whole table fetching for the purpose of CSV export.
The Cake's find() has an internal array processing and the returned result set has to be looped again explicitly. I want to optimize the code by avoiding the array processing of large data twice.
Related issue: https://github.com/cakephp/cakephp/issues/6426
At first be sure, that you only fetch the data you really yreally need. Ideally you get everything you need with $this->YourModel->recursive = -1
Often performance problems arise due to many connected data.
When you have checked this I think a loop would be the best solution where you fetch the desired data in chunks via an between condition. Although I am not sure if this will help you.
Why do you want to go through the whole table? Do you perform some maintenance like e.g. filling a new field or updating a counter? Maybe you can achieve the goal better than by trying to fetch a whole table.
I'm not sure that I have the terminology correct but basically I have a website where members can subscribe to topics that they like and their details go into a 'favorites' table. Then when there is an update made to that topic I want each member to be sent a notification.
What I have so far is:
$update_topic_sql = "UPDATE topics SET ...My Code Here...";
$update_topic_res = mysqli_query($con, $update_topic_sql)or die(mysqli_error());
$get_favs_sql = "SELECT member FROM favourites WHERE topic = '$topic'";
$get_favs_res = mysqli_query($con, $get_favs_sql);
//Here I Need to update the Members selected above and enter them into a notes table
$insert_note_sql = "INSERT INTO notes ....";
Does anyone know how this can be achieved?
Ok, so we've got our result set of users. Now, I'm going to assume from the nature of the question that you may be a bit of a newcomer to either PHP, SQL(MySQL in this case), web development, or all of the above.
Your question part 1:
I have no idea how to create an array
This is easier than what you may think, and if you've already tried this then I apologize, I don't want to insult your intelligence. :)
Getting an array from a mysqli query is just a matter of a function call and a loop. When you ran your select query and saved the return value to a variable, you stored a mysqli result set. The mysqli library supports both procedural and object oriented styles, so since you're using the procedural method, so will I.
You've got your result set
$get_favs_res = mysqli_query($con, $get_favs_sql);
Now we need an array! At this point we need to think about exactly what our array should be of, and what we need to do with the contents of the request. You've stated that you want to make an array out of the results of the SELECT query
For the purposes of example, I'm going to assume that the "member" field you've returned is an ID of some sort, and therefore a numeric type, probably of type integer. I also don't know what your tables look like, so I'll be making some assumptions there too.
Method 1
//perform the operations needed on a per row basis
while($row = mysqli_fetch_assoc($get_favs_res)){
echo $row['member'];
}
Method 2
//instead of having to do all operations inside the loop, just make one big array out of the result set
$memberArr = array();
while($row = mysqli_fetch_assoc($get_favs_res)){
$memberArr[] = $row;
}
So what did we do there? Let's start from the beginning to give you an idea of how the array is actually being generated. First, the conditional in the while loop. We're setting a variable as the loop condition? Yup! And why is that? Because when PHP (and a lot of other languages) sets that variable, the conditional will check against the value of the variable for true or false.
Ok, so how does it get set to false? Remember, any non boolean false, non null, non 0 (assuming no type checking) resolves to true when it's assigned to something (again, no type checking).
The function returns one row at a time in the format of an associative array (hence the _assoc suffix). The keys to that associative array are simply the names of the columns from the row. So, in your case, there will be one value in the row array with the name "member". Each time mysqli_fetch_assoc() is called with your result set, a pointer is pointed to the next result in the set (it's an ordered set) and the process repeats itself. You essentially get a new array each time the loop iterates, and the pointer goes to the next result too. Eventually, the pointer will hit the end of the result set, in which case the function will return a NULL. Once the conditional picks up on that NULL, it'll exit.
In the second example, we're doing the exact same thing as the first. Grabbing an associative array for each row, but we're doing something a little differently. We're constructing a two dimensional array, or nested array, of rows. In this way, we can create a numerically indexed array of associative arrays. What have we done? Stored all the rows in one big array! So doing things like
$memberArr[0]['member'];//will return the id of the first member returned
$memberArr[1]['member'];//will return the id of the second member returned
$lastIndex = sizeof($memberArr-1);
$memberArr[$lastIndex]['member'];//will return the id of the last member returned.
Nifty!!!
That's all it takes to make your array. If you choose either method and do a print_r($row) (method 1) or print_r($memberArr) (method 2) you'll see what I'm talking about.
You question part 2:
Here I Need to update the Members selected above and enter them into a notes table
This is where things can get kind of murky and crazy. If you followed method 1 above, you'd pretty much have to call
mysqli_query("INSERT INTO notes VALUES($row['member']);
for each iteration of the loop. That'll work, but if you've got 10000 members, that's 10000 inserts into your table, kinda crap if you ask me!
If you follow method two above, you have an advantage. You have a useful data structure (that two dim array) that you can then further process to get better performance and make fewer queries. However, even from that point you've got some challenges, even with our new processing friendly array.
The first thing you can do, and this is fine for a small set of users, is use a multi-insert. This just involves some simple string building (which in and of itself can pose some issues, so don't rely on this all the time) We're gonna build a SQL query string to insert everything using our results. A multi insert query in MySQL is just like a normal INSERT except for one different: INSERT INTO notes VALUES (1),(2),(x)
Basically, for each row you are inserted, you separate the value set, that set delineated by (), with a comma.
$query = 'INSERT INTO notes VALUES ';
//now we need to iterate over our array. You have your choice of loops, but since it's numerically indexed, just go with a simple for loop
$numMembers = sizeof($memberArr);
for($i = 0; $i < $numMembers; $i++){
if($i > 0){
$query .= ",({$membersArr[$i]['member']})";//all but the first row need a comma
}
else {
$query .= "({$membersArr[$i]['member']})";//first row does not need a comma
}
}
mysqli_query($query);//add all the rows.
Doesn't matter how many rows you need to add, this will add them. However, this is still going to be a costly way to do things, and if you think your sets are going to be huge, don't use it. You're going to end up with a huge string, TONS of string concats, and an enormous query to run.
However, given the above, you can do what you're trying to do.
NOTE: These are grossly simplified ways of doing things, but I do it this way because I want you to get the fundamentals down before trying something that's going to be way more advanced. Someone is probably going to comment on this answer without reading this note telling me I don't know what I'm doing for going about this so dumbly. Remember, these are just the basics, and in no way reflect industrial strength techniques.
If you're curious about other ways of generating arrays from a mysqli result set:
The one I used above
An even easier way to make your big array but I wanted to show you the basic way of doing things before giving you the shortcuts. This is also one of those functions you shouldn't use much anyway.
Single row as associative(as bove), numeric, or both.
Some folks recommend using loadfiles for SQL as they are faster than inserts (meaning you would dump out your data to a file, and use a load query instead of running inserts)
Another method you can use with MySQL is as mentioned above by using INSERT ... SELECT
But that's a bit more of an advanced topic, since it's not the kind of query you'd see someone making a lot. Feel free to read the docs and give it a try!
I hope this at least begins to solve your problem. If I didn't cover something, something didn't make sense, or I didn't your question fully, please drop me a line and I'll do whatever I can to fix it for you.
This is what i am doing now : - in PHP
foreach($array as $value)
{
$query = select abc from tblname where colname =" .$value.
// fire query
}
then i create array of these values and display accordingly.
The PROBLEM: -
I have applied foreach, which fires the query every time it encounters a value in the array.
result, if i have 10 values in my array it fires 10 queries. and uses network 10 times, result slow output.
What i want -
I want to give the array to a stored procedure which shall give me a resultset which will have the outputs corresponding to all the elements in the array.
I know this can be done but do not know how.
the mysql doesnot take arrays as datatype.
the result shall be that network shall be used only once, despit of any number of values in the array.
LIKE -
StoredProcedure(inputMysqlARRAY) // not possible, need a workaroung
{
// fire simple select(same) query for each value.
}
then call this stored procedure from PHP and input array. // need workaround.
You just have to be smarter about your calls. For instance, keeping cached DB objects around and that sort of thing.
Without knowing more about your code (your question is fairly garbled), it seems that if your query is something like this:
$query = "select abc from tblname where colname =" .$value; // run 10 times.
You really just need to write smarter code:
$values = array(); // Now, populate this array.
// When you're done, run the query:
$query = 'select abc from tblname where colname IN (\''.implode('\',\'', $values).'\')';
Generally, we refer to this as Dynamic SQL and is the underpinning for how things are typically done today. A stored procedure (or, based on how I read your question, stored function) is useful at times, but is somewhat antiquated as a first-order methodology for interfacing with SQL. The DB guys still sometimes swear by it, but I think that even they are fairly well in consensus that smarter queries are always better.
I am trying to find out which is the proper way to fetch data from my database. Either way works, but what's the difference; an in-depth explanation?
$sql = mysql_query("SELECT * FROM _$setprofile");
while($row = mysql_fetch_array($sql)) {
$username = $row['user'];
$password = $row['pass'];
echo "$username:$password";
}
versus the function below...
$sql = mysql_query("SELECT user,pass FROM _$setprofile");
while($row = mysql_fetch_row($sql)) {
echo "$row[0]:$row[1]";
}
This is something I've always wanted to know.
The difference is you're re-assigning the variables in the first example. But you could just say:
while(list($username, $password) = mysql_fetch_array($sql)) {
echo "$username:$password";
}
Or you could pull out a hash
while($row = mysql_fetch_assoc($sql)) {
echo "{$row['username']}:{$row['password']}";
}
The right way depends on the application or your preference, I personally avoid the numeric indexed arrays unless I specifically need them. Who wants to try to keep a mental tab of what data is in which index?
The difference is that fetch_array extracts an array containing BOTH numerical and associative indexes (unless you provide an extra option to tell it otherwise), while fetch_row only gets numerical indexes and fetch_assoc only gets associative indexes. Usually, you don't want both.
Use fetch_assoc instead of fetch_array - that ONLY gets you an array with associative indexes. That means it'll run a bit faster (it has to do less work), but the code will be just as clear.
From a functional perspective, the difference is minimal. However, the former has the problem that you're fetching more from the database than you need (SELECT *). It's generally recommended not to select more than you actually need.
There's no much difference internally. Both ordinal positions and column names are available in the result set metadata within the MySQL client API, regardless.
Regarding usage, both can be handy in different circumstances. Referencing columns by name is more mnemonic, results in (semi-) self-documenting code, allows you to change the position or number of columns in the query without breaking your code, etc.
But fetching by ordinal is hand too sometimes. For example:
SELECT u.name, d.name FROM user u JOIN department d USING (dept_id)
Now you have two columns with the same name in the result set. If you fetch an associative array, one overwrites the other because an assoc array can only have one value per key. So $row["name"] is one of the names, and you don't necessarily know which it's going to be.
SELECT d.name, COUNT(*) FROM user u JOIN department d USING (dept_id) GROUP BY dept_id
Now you have a column that has no alias, and depending on the RDBMS brand you use, it could invent a funny-looking alias automatically, or else just use the whole expression as the key for the assoc array. So it's nice to be able to use ordinal position instead of column name in this case.
(It's funny how my writing style becomes more informal and chatty when I'm listening to the StackOverflow podcast while I'm writing.)