I'm currently trying to write a simple ORM with PHP and mysql. I want the orm class to be able to work with joined tables.
So here's my problem, the following code shows how I map the data the query yields into an array.
public function execute_query($db_connection)
{
$query = '';
foreach($this->sql_query as $query_part)
$query .= $query_part;
$result = $db_connection->query($query);
while($row = $result->fetch_assoc())
{
array_push($this->m_Data, $row);
}
}
db_connection is a mysqli object.
sql_query contains all the different query parts (e.g. sql_query['join'] etc.).
m_Data is the array that contains the data read from the db.
My specific problem now is when I'm using a join statement in my query this function will just override fields with the same name in my m_Data array. Also if I dont save the name's of the table the specific field data is coming from, I later can't update the tables with the same join statement.
tl,dr. I need to be able to not only save the table data like this: m_Data{ 'field_name' => 'value' } but I also need to save the table name the field is selected from. I could then save the data like this m_Data{ 'table_name.field_name' => 'value' } which enables me later to generate a query to update the joined tables successfully.
I cant seem to find any information on how to get the origin table name for each field I pull out of the result.
If it isnt possible with mysqli I'd much appreciate it if you point me in the right direction.
extra short problem statement:
I need to get a result set and read each row seperatly. For each row I need the following information for every field selected: field_name, table_name, value.
There must be a simple answer to this but I seem to be searching for the wrong keywords to find a solution.
I hope I've written this understandable enough.
Seems to me that you should store table column values in an object, so if you have a related table, the column values would be stored in a separate object - and so would not interfere with the values in your primary table.
In general you might work with the ORM this way:
// Make joined query
$rows = ...
foreach($rows as $row)
{
// $row just refers to the primary table
echo $row->id;
// You get a many:1 related table this way
echo $row->getRelatedRow()->value;
// You get a 1:many rows this way
$rows = $row->getOtherRelatedRows();
}
Depending on how you set up your query options, getting related data may or may not initiate further SELECTs to get the required data.
mysqli_result::fetch_fields has useful things:
http://www.php.net/manual/en/mysqli-result.fetch-fields.php
table
orgtable
field type
etc
Related
I have been trying to figure out how to check if any of one column's items present in another column in Codeigniter....
I have Bike,Car,Bus in a column(Vehicles) in a table1...
I also have Bus,Helicopter,Ship,Car in a column(Interested) in table2..
How to check if any of table2 interested column's items present in table1 vehicles column...
I tried like this...
$query = $this->db->get('table2');
foreach($query->result() as $row)
{
$a = explode(',', $row->interested);
$this->db->where_in('Vehicles', $a);
$query = $this->db->get('table1');
foreach($query->result() as $row2)
{
echo $row2->ID;
}
}
Could it be done ?? Please Help me... Thanks in advance....
It is very hard to help you without seeing the tables and how you are relating one to the other (such as user_id).
What you should do is two queries. One query to get the data from table 1 of the vehicles you are interested in. Then run through the result set and create a simple array of those vehicles in php. Then do a second query using where_in to select all the rows that are in the chosen vehicles array.
Your method is bad because the number of db queries depends on the size of the result set of your first query. You might find your code trying to do hundreds of database queries.
If you show a diagram of your tables, I could write some example code for you.
Here are the docs for where_in: https://www.codeigniter.com/user_guide/database/query_builder.html#CI_DB_query_builder::where_in
What is the syntax for inserting data from one table to another table, using codeigniter active record syntax? I tried the usual mysqli query and it works, but I want to use CodeIgniter Active Record syntax for consistency.
I tried playing with these CodeIgniter Active Record queries but still no luck:
function insert_into()
{
$this->db->insert('table1');
$this->db->set('to_column');
$this->db->select('from_column');
$this->db->from('table2');
}
I think the best thing to accomplish that is fetching the data you want from one table using the get method, then using one of the query results grabber functions (like result() ), iterate over the rows one by one using the insert() method.
Putting this in code:
$query = $this->db->get('table1');
foreach ($query->result() as $row) {
$this->db->insert('table2',$row);
}
Of course, i suppose that table1 has exactly th same structure as table2 (the same column names and data types for each column). If that is not the case, you will have to map the columns from one table to the another using assignments, but if that is the case your code will be more wide.
Copies $source_table into $archive_table:
if(($this->db->table_exists($source_table) && ($this->db->table_exists($archive_table)){
if ($this->db->query("CREATE TABLE $archive_table LIKE $source_table")){
if($this->db->query("INSERT $archive_table SELECT * FROM $source_table")){
echo 'copied ok';
}
}
}
Neater than looping over the entire result set and inserting one row at a time.
Ok i have two tables with a left join. Let call table one "people" and the second table "dog". I have left joined the tables by an id:
"SELECT * FROM people
LEFT JOIN dog ON people.PK = dog.fk";
My problem is that both tables have a column title "name." When i echo back out the $_POST['name'] variable it give the same value for both fields I tried
echo $_POST['people.name']
echo $_POST['dog.name']
but this isn't returning any data so this must be incorrect. Can someone help me fix my problem without having to change my column names. Thanks you.
The $_POST superglobal contains data submitted from a form. It does not contain data from database queries. You probably do something like this (pseudocode):
$result = database_query (
"SELECT * FROM people LEFT JOIN dog ON people.PK = dog.fk"
);
The data you want is now contained in the variable named $result. How you access it will depend on your database access method, but typically you would fetch a row from the result object, perhaps as an associative array.
$row = database_fetch_assoc($result);
Then the array $row would contain your data.
echo $row['name'];
You might need to alias the column names in the query in order to be able to access the values of both name columns.
Alias the column names and don't use SELECT * but specify columns manually:
SELECT people.name AS people_name, dog.name AS dog_name
FROM people
LEFT JOIN dog ON people.PK = dog.fk
Then you can access the fields through ['people_name'] and ['doc_name'].
Depending on your table structure and which field you actually need you could also SELECT table1.*, table2.somecol AS t2_somecol - that's handy if you need everything from the first table but only a few fields from the second one.
Oh, and you really shouldn't put stuff into $_POST. It's meant to be populated by PHP with POST data - and data coming from your DB is not really POST data.
I'm trying to do a customizable and extendable profile system for my CMS. From the user perspective it is straight forward, but for the admin I want all data, including the profile data, to be searchable. Profile fields may be added by "plugins", which may also add new fields to search on. I don't know if what I'm trying to do with MySQL to make this work is possible or if I'm going at it completely the wrong way.
So I have the users stored in one table (users), with columns for id, email, password and access_level.
I then have another table with profile information (profiles), stored as user_id, parameter and value. The parameter could eventually be put into a separate table again (so it isn't repeating itself), but for now I'll leave it like this.
The parameter and value are basically the profile data. For example, parameter may be "age" and the value may be "22".
What I want to try and do, is select the users table, with the profile information joined so the parameter is mapped to an additional column. So it ends up like so, straight from MySQL:
id email password access_level age
1 a#a.com ***** 1 22
2 b#b.com ***** 2 25
3 c#c.com ***** 2 25
I've been looking at pivot tables all afternoon, but from all I can see the "column name" is pre-defined. In this case I want the "column name" to come from the row itself.
If it isn't possible to do it with a single query, what other methods are there? I'm using PHP if the best method is to do it via that.
Any suggestions would be much appreciated. :)
Well, if you need to know the column names in advance, you can query the information_schema database:
SELECT COLUMN_NAME
FROM information_schema.COLUMNS
WHERE TABLE_NAME='your table'
However, that gets the raw column names. If you're aliasing in your query, you'll have to fetch them indirectly:
SELECT somefield AS alias1, otherfield AS alias2
FROM ...
and then
$stmt = mysql_query($query);
$first = true;
while($row = mysql_fetch_assoc($stmt)) {
if ($first) {
$column_names = array_keys($row);
... display column names here
$first = false;
}
... output row here
}
I was wondering if anyone knew how to get the metadata info from a Zend_Db_Table_Rowset class when using joins in the query that produced that result set? It's easy when there are no joins involved.. for example:
foreach ($rowset as $row) {
$info = $row->getTable()->info(Zend_Db_Table_Abstract::METADATA);
Zend_Debug::dump($info); // outputs array of column info including data type
}
But when I do that to a row that came from a query using joins I just get the data from the main table I was selecting from..
Jose, what kind of metadada info do you need? Maybe there is an alternate way to achieve what you want. Since the joins are always done from one table (and you join it to others) I think you will always get the metadata info for the first one.
By any chance are you doing dynamic joins?