ZF last insert id gives me back '0' - mysql

When I try to use the function '->lastInsertId()' to retrieve the lat ID of a table I get back '0'.
I can't find the solution. My table is an autoincrement
I try to get it in the controller with this code.
$reviews = new Application_Model_DbTable_Reviews();
$lastId = $reviews->getAdapter()->lastInsertId();
echo $lastId;
I hope someone can help me.
With kind regards,
Nick

Well this stuff is not mention in docs but it works for e.g
if you have table name 'Book' with PK book_id , FK user_id and 'User' table with PK user_id
<<Book>>
*book_id
title
user_id
<<User>>
*user_id
name
age
then
$userTb = new Model_DbTable_User();
$user = $userTb->createRow();
$user->name = "jason";
$user->age = 25;
$user->save();
//well after saving the record ZF populates PK for you so now you have read only access to auto incremented PK simply by $userTb->user_id;
so
$bookTb = new Model_DbTable_Book();
$book = $bookTb->createRow();
$book->title = 'php';
$book->user_id = $user->user_id;
$bookId = $book->save(); // this is another way of accessing auto generated PK at insert tim .

Related

Insert Rows with using the result from a group of select best way to do it

I have an array of tags inserted in my database, and I need to insert them in another table with itemID and tagID.
The thing is that i don't have the tagID - instead I have a TagName with the name. I need to get the tagID so I can insert it afterward, but I'm wondering if this is possible to achieve in one single query.
I mean search for the name, then get its tagID and then insert it the array, or even inserting them one by one would work.
if I understood you, my ways is: create two tables first. If you know better way, please let me know.
Table Tag
id keyword
Table C_Tag
id tag_id user_id
Foreign key Tag(id) Reference C_Tag (tag_id)
<?php
$tag=$_POST['tag_name'] //get the tag name
$current_user=$_POST['users_id'];// get the current user id
include 'db_tag.php';
$stmt = $db->prepare("SELECT keyword, id FROM Tag WHERE keyword = :tag ");
$stmt->bindParam(':tag', $tag);
$stmt->execute();
$row_tag = $stmt->fetchALL(PDO::FETCH_ASSOC);
foreach ($row_tag as $row_tag){
}
//if the keyword exist, only update the C_Tag table
if ($row_tag['term'] == $tag){
$stmt = $db->prepare("SELECT t.id, t.keyword, ct.tag_id, ct.user_id FROM Tag t , C_Tag ct WHERE t.id=ct.tag_id ");
$stmt->bindValue(':current_id',$current_user);
$stmt->execute();
$row = $stmt->fetchALL(PDO::FETCH_ASSOC);
foreach ($row as $row){
}
$row_id=$row['id'];
$row_tag_id=$row['tag_id'];
$row_user_id=$row['user_id'];
if( $current_user == $row_user_id && $row_id == ! $row_tag_id ){
//make sure same user cannot enter duplicate keyword
$stmt = $db->prepare ("INSERT INTO C_Tag (user_id, tag_id)
SELECT :current_id, id
FROM tag
WHERE keyword=:keyword
");
$stmt->bindValue(':current_id',$current_user);
$stmt->bindValue(':keyword', $tag);
$stmt->execute();
}
} else {
//if the keyword is new, I will insert it into both table
}
?>
this appears to be the solution
How to copy a row and insert in same table with a autoincrement field in MySQL?
insert into zr1f4_k2_tags_xref (id, tagID, itemID) select NULL, tagID, #itemID from zr1f4_k2_tags where name=#tagName
but i cant make it work.
this are the tables
zr1f4_k2_tags
id int(11)
name varchar(255)
published smallint(6)
zr1f4_k2_tags_xref
id int(11)
tagID int(11)
itemID int(11)
I'm trying to insert the ID of the tag related to the tagname and item ID which ill add explicitly. and the id is autonumeric

Insert new column, increment all rows

Is this possible using only mysql:
Insert a new column and example - "pos".
Every row in the table has to have unique,incresing value of "pos" like - 1,2,3,4,5.
In php this would be an easy job:
$query = "SELECT * FROM example";
$result = mysql_query($query) or die(mysql_error());
$counter = 0;
while($row = mysql_fetch_array($result)){
mysql_query( "UPDATE example SET pos = ".++$counter." WHERE id = ".$row['id']." );
}
As already suggested, the most efficient solution is to use auto incremental on pos.
Alternatively if your use case do not permit you, then try similar:
"UPDATE example SET pos = ((select max(pos) from example) +1) WHERE id
= ".$row['id']."
yes you can do it like that
UPDATE example SET pos = pos+1 WHERE id = ".$row['id']."
Give your pos mysql field the auto_increment attribute - this will index it, make it unique, and increment by 1 on each insert

Is it possible to have table in table (mysql)?

Suppose I defined music as a table and gave it 3 columns: album, artist, and track:
CREATE TABLE music (
id int auto_increment primary key,
album varchar(45) not null,
artist varchar(30) not null,
track int(8)
);
Now I want another table releasedy which contains a column:
'Year' and the table music
I suppose for that I have to bind some row from table music with year from table releasedy in another table. So I can know which year contains which musics. If I'm not wrong I have to do that with foreign key. How should I proceed?
You do not want "a table in a table", instead you want to match records from one table with records from another table in a query. You can create a view on top of this query and use the view later as it if were a regular table.
As you guessed, establish a foreign key relationship, then JOIN the two tables.
There is no "table in a table", only tables and relations between them.
Table releasedy will have 2 columns, musicId & year. musicId is the foreign key to your music table.
Join (as you called bind) these two:
SELECT *
FROM music m
INNER JOIN releasedy r ON m.id = r.musicId
WHERE year = ..
Which is all overkill in this example but it illustrates the "binding" you want.
class Functions {
public function getRows($sql){
$result = mysql_query($sql);
while($row = mysql_fetch_assoc($result)){
$data[] = $row;
}
return $data;
}
public function getMusicData(){
$data = $this->getRows("SELECT * FROM music");
return base64_encode(serialize($data));
}
}
$func = new Functions();
$music = $func->getMusicData();
$sql = "insert into releasedy (id,Year) values (NULL,'".$music."')";
mysql_query($sql);
$id = 'your necessary id'; $read = "select * from releasedy where id = ".(int)$id; $data = mysql_query($read); $musics = unserialize(base64_decode($data['Year'])); foreach($musics as $music){ // do something }

Insert on first request; update on all subsequent requests

I'm inserting a row into a MySQL database table. On the first insertion I want a new row to be added, but after that I just want that row to be updated. Here's how I'm doing it. An Ajax request calls the following php file:
<?php
include "base.php";
$bookID = $_POST['bookID'];
$shelfID = $_POST['shelfID'];
$userID = $_SESSION['user_id'];
$query = mysql_query("SELECT shelfID FROM shelves WHERE userID = '$userID' AND shelfID = '$shelfID' AND bookID = '$bookID'");
if (mysql_num_rows($query) == 0) {
$insert = "INSERT INTO shelves (bookID,shelfID,userID) VALUES ('$bookID','$shelfID','$userID')";
mysql_query($insert) or die(mysql_error());
} elseif (mysql_num_rows($query) == 1) { //ie row already exists
$update = "UPDATE shelves SET shelfID = '$shelfID' WHERE userID = '$userID' AND bookID = '$bookID'";
mysql_query($update) or die(mysql_error());
}
?>
As it stands it adds a new row every time.
You should consider using PDO for data access. There is a discussion on what you need to do here: PDO Insert on Duplicate Key Update
I'd flag this as duplicate, but that question is specifically discussing PDO.
You can use the INSERT ... ON DUPLICATE KEY UPDATE syntax. As long as you have a unique index on the data set (i.e. userid + shelfid + bookid) you are inserting, it will do an update instead.
http://dev.mysql.com/doc/refman/5.5/en/insert-on-duplicate.html

how can I connect these two tables in sql?

i need to take only the items from the table "__sobi2_item" that are in the same country of the user.And use this results for the rest of the function Showupdatelisting. This is my php script:
<?php
function showUpdatedListing()
{
//i found the user country field value...
global $database;
$user =& JFactory::getUser();
$userId = $user->get( 'id' );
$sql = "SELECT (id) FROM #__community_fields WHERE fieldcode= 'FIELD_COUNTRY'";
$database->setQuery( $sql );
$fieldID = $database->loadResult();
$sql = "SELECT (value) FROM #__community_fields_values WHERE field_id= {$fieldID} && user_id= {$userId}";
$database->setQuery( $sql );
$usercountry = $database->loadResult();
// From all the entries i take only ones that have country field like the user has...
$query = "SELECT `data_txt`, `itemid`, `fieldid` FROM `#__sobi2_fields_data` WHERE (`fieldid` = 6) AND ('data_txt' = {$usercountry})";
$database->setQuery($query);
$ResultsArray = $database->loadObjectList();
// We need something here like a Query to load only the entries from $ResultsArray... ??
//....instead of this...
$config =& sobi2Config::getInstance();
$database = $config->getDb();
$now = $config->getTimeAndDate();
$query = "SELECT itemid FROM #__sobi2_item WHERE (published = 1 AND publish_down > '{$now}' OR publish_down = '{$config->nullDate}') ORDER BY last_update DESC LIMIT 0, 30";
$database->setQuery($query);
$sids = $database->loadResultArray();
// ......... show update function goes on...
?>
can anyone help me to connect and adjust these query? thanks.
NB:with the last query (4) i need to filter items of the $ResultsArray taking only ones published and ordering them by last_update. i know it is wrong and now there is no connection with the query before. This is how i have tables in mysql:
_sobi2_fields_data:
itemid
fieldid
data_txt --->(is a description column for each field)
_sobi2_item:
itemid
published --->( 1 if true, 0 if false )
last_update --->(date of the last update for the item, also equal to the publication date if there are no changes)
thanks.
I don't know what you are trying to ask as well. Your last query (number 4) doesn't make sense to me, how is it linked to the above queries?
[EDIT] I've linked your 4th table above assuming itemid is the primary key for the items in sobi2_item table and that the value is linked to the sobi_fields_data table via itemid.
SELECT
cf.id,
sfd.data_txt,
sfd.itemid,
sfd.fieldid
FROM #__community_fields cf
INNER JOIN #__community_fields_values cfv ON cf.id=cfv.field_id
INNER JOIN #__sobi2_fields_data sfd ON cfv.value=sfd.data_txt
INNER JOIN #__sobi2_item si ON sfd.itemid=si.itemid
WHERE cf.fieldcode='FIELD_COUNTRY'
AND cfv.user_id=$userId
AND sfd.fieldid=6
AND si.published=1
AND (si.publish_down > '{$now}' OR si.publish_down = '{$config->nullDate}')
ORDER BY si.last_update DESC LIMIT 0, 30
Good luck!