I have 2-3 questions regarding my sql INSERT and how to go about combining multiple $_POST into one field.
i'm having problems with my INSERT statement everything was working till I added m_id=".intval($id)."
for field m_age I need to combine/insert the following three $_POST['month'] $_POST['day'] $_POST['year'] into it. Should I create a var $age = $_POST['month'] + ...; then insert $age into m_age separately?
same as 2. I want combine $_POST['feet'] and $_POST['inches'] into m_height
code:
$fields = explode(" ", "m_id m_pos m_name m_age m_btype m_height");
$query = "INSERT INTO meminfo SET m_id=".intval($id).", ".dbSet($fields, "m_" + $_POST['add']);
Without knowing what your dbSet() function looks like I can hazard a few guesses:
Your $fields array contains an m_id field, which you are already setting explicitly when you added the m_id=".intval($id)." portion. This could be why you're having problems there.
You want to insert into an "age" field using month, day, and year? Are you calculating the age based on those 3 parameters assuming they are a birthdate? If so I'd say you probably are best off doing that calculation and assigning the result to an $age variable and using that in your insert.
Same as #2 although conversion of feet and inches to a combined total in one of those units is a simpler calculation and so could be done inline with your insert statement.
Basically when it comes down to 2 & 3 you can go either way but your code will probably be much more readable (and therefore maintainable by you and/or others in the future) if you separate out the calculations from the formation of the SQL query.
everything was working till I added m_id=".intval($id)."
this is not true.
While m_id=".intval($id)." being correct statement,
a dbSet($fields, "m_" + $_POST['add']); one makes absolutely no sense.
but you are right, the dbSet() function is intended to be used like that
$_POST['m_id'] = $id;
and 'm_id' will be added to the set automatically. Same for the other artificial fields
However, adding an id (assuming autoincrement field) into insert query makes no sense.
Anyway, seeing your struggle with basic PHP syntax I am going to withdraw my proposal for using dbSet() function.
You have to write your inserts by hand, until you get familiar with them.
Otherwise no function will do no good for you.
The particular problem obviously coming from the m_ prefix you are using for all your fields. A strange whim making things unnecessary complicated. You'd better get rid of it.
Related
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.
In the nested set model we have LEFT and Right columns
the first time when the table is empty, what i need to insert to the RIGHT column, if i don't know how many children will i have
LEFT 1 - forever
RIGHT ? - what value goes here??
how to make it dynamic? not static.
ps: using php
I'm assuming from your tags and title that you are looking for a solution that works with MySQL.
Yes, you are right that unless you know the number of elements in advance the value for right needs to be calculated dynamically. There are two approaches you can use:
You could start with the least value that works (2 in this case) and increase it later as needed.
You could just make a guess like 10000000 and hope that's enough, but you need to be prepared for the possibility that it wasn't enough and may need adjusting again later.
In both cases you need to implement that the left and right values for multiple rows may need to be adjusted when inserting new rows, but in the second case you only actually need to perform the updates if your guesses were wrong. So the second solution is more complex, but can give better performance.
Note that of the four common ways to store heirarchical data, the nested sets approach is the hardest to perform inserts and updates. See slide 69 of Bill Karwin's Models for Heirarchical Data.
OK, I know the technical answer is NEVER.
BUT, there are times when it seems to make things SO much easier with less code and seemingly few downsides, so please here me out.
I need to build a Table called Restrictions to keep track of what type of users people want to be contacted by and that will contain the following 3 columns (for the sake of simplicity):
minAge
lookingFor
drugs
lookingFor and drugs can contain multiple values.
Database theory tells me I should use a join table to keep track of the multiple values a user might have selected for either of those columns.
But it seems that using comma-separated values makes things so much easier to implement and execute. Here's an example:
Let's say User 1 has the following Restrictions:
minAge => 18
lookingFor => 'Hang Out','Friendship'
drugs => 'Marijuana','Acid'
Now let's say User 2 wants to contact User 1. Well, first we need to see if he fits User 1's Restrictions, but that's easy enough EVEN WITH the comma-separated columns, as such:
First I'd get the Target's (User 1) Restrictions:
SELECT * FROM Restrictions WHERE UserID = 1
Now I just put those into respective variables as-is into PHP:
$targetMinAge = $row['minAge'];
$targetLookingFor = $row['lookingFor'];
$targetDrugs = $row['drugs'];
Now we just check if the SENDER (User 2) fits that simple Criteria:
COUNT (*)
FROM Users
WHERE
Users.UserID = 2 AND
Users.minAge >= $targetMinAge AND
Users.lookingFor IN ($targetLookingFor) AND
Users.drugs IN ($targetDrugs)
Finally, if COUNT == 1, User 2 can contact User 1, else they cannot.
How simple was THAT? It just seems really easy and straightforward, so what is the REAL problem with doing it this way as long as I sanitize all inputs to the DB every time a user updates their contact restrictions? Being able to use MySQL's IN function and already storing the multiple values in a format it will understand (e.g. comma-separated values) seems to make things so much easier than having to create join tables for every multiple-choice column. And I gave a simplified example, but what if there are 10 multiple choice columns? Then things start getting messy with so many join tables, whereas the CSV method stays simple.
So, in this case, is it really THAT bad if I use comma-separated values?
****ducks****
You already know the answer.
First off, your PHP code isn't even close to working because it only works if user 2 has only a single value in LookingFor or Drugs. If either of these columns contains multiple comma-separated values then IN won't work even if those values are in the exact same order as User 1's values. What do expect IN to do if the right-hand side has one or more commas?
Therefore, it's not "easy" to do what you want in PHP. It's actually quite a pain and would involve splitting user 2's fields into single values, writing dynamic SQL with many ORs to do the comparison, and then doing an extremely inefficient query to get the results.
Furthermore, the fact that you even need to write PHP code to answer such a relatively simple question about the intersection of two sets means that your design is badly flawed. This is exactly the kind of problem (relational algebra) that SQL exists to solve. A correct design allows you to solve the problem in the database and then simply implement a presentation layer on top in PHP or some other technology.
Do it correctly and you'll have a much easier time.
Suppose User 1 is looking for 'Hang Out','Friendship' and User 2 is looking for 'Friendship','Hang Out'
Your code would not match them up, because 'Friendship','Hang Out' is not in ('Hang Out','Friendship')
That's the real problem here.
I have a query to list a set of numbers, for example 1000000 through 2000000, I then run another query in that while loop to see if it matches another table in another database. This part runs fine, but a little slow.
I then need to have another query such that if it returns false, then it does another check on yet another table. The problem I'm having though, is that the check in this table is not as simple as a match.
The table structure on last table is like this:
firstnum
secondnum
This is intended for use in a range of numbers. So row 1 for example might be:
1000023, 1000046
This would mean it's for all numbers between and including those values.
There are thousands of these entries in the DB, and I'm trying to figure out the best way to determine if that particular number I'm searching on exists in that table somewhere, but since it's not a direct match, I'm not sure how to accomplish this. The table is also PostgreSQL while the main queries are MySQL.
It's a bit hard to understand what you're trying to say, but I'm afraid the solution is ridiculously simple: ... WHERE firstnum <= X AND X <= secondnum, where X is the number you are looking for.
I've got this HTML form where I have multiple input elements: text, radio, and so on. These are intended to be options, conditional items to apply in an SQL query in order to pull more specific data from a database.
For example, the first input field is a textbox, the second a radio button, and the third a SELECT with two options. With the first, I would add a LIKE %name% sentence in the SQL query. The second is a radio button group with, let's say, a color, so I would add a WHERE color = $item comparing the one chosen with the database column. The third would pretty much be just like the second.
Now, I guess I could just use if sentences comparing the three items, in order to know which one to add to the SQL query, but my question is: is there a smarter way to do it? Like an array checking if those variables are set (I'm still using an if here, so nevermind).
I program simple things from time to time, since I've never done anything significantly complex, but sometimes, even for simple things, no matter how hard I strive to design something, I just can't.
In this case, I really can't figure (imagine, visualize) how would I structure the PHP code along with the SQL query, in order to add the these three conditions to the WHERE clause.
I'd greatly appreciate if you can help me out here. If you need more details, just let me know.
You can just build your sql statement as you go.
A simple example:
$sql = "SELECT ... WHERE 1=1"; // 1=1 is just an example to get the WHERE out of the way
if (first condition / certain $_POST variable is set)
{
$sql .= " AND LIKE %...%";
}
if (second condition)
{
$sql .= " AND something=...";
}
// etc.
// run query
Just for adding another solution, I can suggest you using stored procedure.
http://www.mysqltutorial.org/mysql-stored-procedure-tutorial.aspx
http://www.brainbell.com/tutorials/MySQL/Using_Stored_Procedures.htm
You'll just need to pass values to a sp and generate where condition inside it.
There's another option to generate parameterized query in PHP to prevent SQL Injections.
Here are some links on this topic.
http://us2.php.net/manual/en/security.database.php
http://www.roscripts.com/PHP_MySQL_by_examples-193.html
http://www.webmasterworld.com/php/3110596.htm
http://am.php.net/mysql_real_escape_string