PDO Riddle (No while loop) - pdo

I just recently learned how to work with PDO database queries, but my latest query isn't working for some reason. All my other queries include arrays and while loops, but I don't think this one requires either, so I may just need to change the query structure somehow.
$stm = $pdo->prepare("SELECT H.N, H.URL, H.Title, H.Subtitle,
H.Site, H.MetaTitle, H.MetaDesc, H.KW, H.Live, A.Article, A.Pagedex
FROM 1_home_pages H
LEFT JOIN 1_home_articles A ON A.Site = H.Site
WHERE H.URL = :MySection AND H.Site = :MySiteId AND H.Live = 1 AND A.Site = :MySiteId AND A.Section = :MySection");
// $stm->execute();
$stm->execute(array(
'MySiteId'=>$MySiteID,
'MySection'=>$MySection
));
$data = $stm->fetchAll();
I added the line $data = $stm->fetchAll();, and it now works - as an array. The foreach statement below displays EVERYTHING in one jumbled mess...
foreach($data as $row) {
print_r($row);
}
To escape the array and just display one item at a time, I tried the following:
$Content = $data['Article'];
echo $Content;
But it doesn't display anything. Can anyone tell me the solution?

I don't know if you made a typo while posting this question, or this is a typo from your source code: you have :MySection and yet while executing you write MySection (without colon). What's more, this line:
WHERE H.URL = :MySection
AND H.Site = :MySiteId
AND H.Live = 1
AND A.Site = :MySiteId
AND A.Section = :MySection");
You used multiple parameters with same name in one statement. Don't know if this is a correct way to do it, since I've never done it. I suggest you try using different names for parameters and see if that helps. Also, what do you mean 'but my latest query isn't working for some reason.' ? What does it return? Does it return anything at all? fetchAll returns multiple rows, that's why you get array.
Instead of $data = $stm->fetchAll(); use $data = $stm->fetch();. It will return next row from your query.

Related

Symfony 6 & Doctrine: delete an array of elements without looping

$em = $this->doctrine->getManager();
$contact = $em->getRepository(Contact::class)->findby(array('id'=>[1,2,3]));
$em->remove($contact);
will give me an error
EntityManager#remove() expects parameter 1 to be an entity object,
array given.
All answers I could find advise me to loop through the array and delete every record separately. I refuse to do so because I only want to send one statement to the database, resulting in SQL: delete from table where id in (1,2,3)
I think the easiest way is to use the query builder, instead a loop over the remove function.
$em = $this->doctrine->getManager();
$qb = $em->getRepository(Contact::class)->createQueryBuilder('c');
$affected = $qb->delete()
->where('c.id IN (:ids)')
->getQuery()
->execute(['ids' => [1,2,3]]);

TYPO3 $query->in('valOne,valTwo,valThree', $arrayTwo)

I have a query in my repository which gets all product by categories and contentTypes.
I am looking for a query like this:
$query = $this->createQuery();
$constraint = $query->in('category', $categories);
if (!empty($contentType)) {
$results = $query->matching(
$query->logicalAnd(
$constraint, $query->in('contentType', $contentType)
)
)
->setLimit((int)$limit)
->setOffset((int)$offset)
->execute()
->toArray();
It works well if 'containType' contains just a single id as string, e.g '261'.
But if it is a string with multiple id's it looks like '261,284,291' and the query does not work longer.
I hope you got all information. Let me know if not :)
You can use GeneralUtility::trimExplode() or in your case probably more specific GeneralUtility::intExplode() to turn the $contentType CSV value into an array of values suitable for QueryInterface::in().

CodeIgniter query from sql

How can I transform this sql to codeigniter query? I have screenshot of an EER diagram to help you understand better. So there are three tables to join. I guess, one is "pjesma", then "izvodjac", and "izvodi_pjesmu". This sql works when I run it and gives me results I want. I am also using pagination so I need limit and offset somehow included.
SELECT pjesma_id, naslov, naziv
FROM pjesma p, izvodjac i, izvodi_pjesmu ip
WHERE p.pjesma_id = ip.pjesma_pjesma_id
AND i.izvodjac_id = ip.izvodjac_izvodjac_id
in model:
public function paginacija_pjesme($limit, $offset) {
$this->db->select('pjesma_id', 'naslov', 'naziv');
$this->db->from('pjesma p');
$this->db->join('izvodi_pjesmu ip', 'p.pjesma_id=ip.pjesma_pjesma_id');
$this->db->join('izvodjac i', 'i.izvodjac_id=ip.izvodjac_izvodjac_id');
$this->db->limit($limit, $offset);
$query = $this->db->get();
return $query->result();
}
EDIT:
So in select I used wrong syntax, this line:
$this->db->select('pjesma_id', 'naslov', 'naziv');
should be like this:
$this->db->select('pjesma_id, naslov, naziv');
A few things, as you are dealing with objects within the query builder class, you can method-chain and make things a little less cluttered.
You are maybe getting an ambiguous column error, joining and not prefixing your select. Hard to tell without the error being posted you are facing.
Always best to (just in case) set defaults to your method arguments as well, in case you pass a blank variable (or don't need to for whatever reason).
When you are using multiple tables in the FROM statement you are actually doing a CROSS JOIN, and your new code is giving INNER JOIN,trying the join syntax direct to your SQL server might help as you are not actually doing the same thing between your first written query, and the codeigniter one..
Try the below with LEFT join just to see... If there are NULL joins using INNER they will be omitted
public function paginacija_pjesme($limit = 10, $offset = 0) {
$query = $this->db->select('p.pjesma_id, p.naslov, i.naziv')
->from('pjesma p')
->join('izvodi_pjesmu ip', 'p.pjesma_id = ip.pjesma_pjesma_id', 'left')
->join('izvodjac i', 'i.izvodjac_id = ip.izvodjac_izvodjac_id', 'left')
->limit($limit, $offset)
->get();
return $query->result();
}
Are you getting any errors? what do you see if you print_r($query->result()) ?
try also spitting out $this->db->last_query() - this will output the SQL codeigniter has build. Then running this directly to your database, and see the results from there. You might even see the issue without needing to run it.
This is an example of what your current codeigniter code is generating (as you can see, different to your original query):
SELECT pjesma_id, naslov, naziv
FROM pjesma p
INNER JOIN izvodi_pjesmu ip ON p.pjesma_id = ip.pjesma_pjesma_id
INNER JOIN izvodjac i ON i.izvodjac_id = ip.izvodjac_izvodjac_id
# LIMIT 10,0

PHP values inside pdo->query or/and prepared statements

I'm limiting the amount of comments shown on the page by 2, $second_count counts how many posts are if more than 2 it limits and show's a Show All comments, that's what this is for.
If you look into the variable $limitPost, how do I add parameter inside it.
This is what I'm trying to accomplish but with PDO.
$limitPost = "DESC LIMIT $second_count,2"; but this can lead to SQL INJECTIONS to my understanding.
PUBLIC FUNCTION userComments($post_iD,$second_count)
{
$limitPost = "DESC LIMIT 2";
$sth = $this->db->prepare("SELECT C.com_id, C.uid_fk, C.comment, C.created, U.username, U.photo
FROM comments C, users U
WHERE U.status='1' AND C.uid_fk = U.uiD
AND C.msg_id_fk = :postiD
ORDER BY C.com_id < :second_count");
$sth->bindParam(':postiD', $post_iD, PDO::PARAM_INT);
$sth->bindParam(':second_count', $limitPost, PDO::PARAM_INT);
$sth->execute();
$data = $sth->fetchAll();
return $data;
}
UPDATE
This is what $second_count is, it it's just counting if there are 2 comments showing, it'll hide all the rest and if I press show all comments it'll expand.
<?php
$x=1;
if($x){
$comment_count = count($commentsarray);
$second_count = $comment_count-2;
if($comment_count>2){
?>
<div class="comment_ui" id="view<?php echo $post_iD;?>">
Show all <?php echo $comment_count;?> comments
</div>
<?php
$commentsarray = $Wall->userComments($post_iD, $second_count);
}
}
?>
alright:
If you look into the variable $limitPost, how do I add another
variable inside it.
This is what I'm trying to accomplish but with PDO.
impossible <- that is the answer to your question
instead of :
:second_count
try:
DESC LIMIT 2
into the prepared statement. You really do not need the parameter :second_count in your prepared statement since it is a constant string.
SQL injections would be possible if :second_count was an input by a user, since is it constant, nothing like that is possible.
Why what you are doing is not working:
DESC LIMIT 2 is not an integer parameter, so the bind should fail or give out junk.
If you were to use PDO::PARAM_STR on the bind, :second_count would be put into qoutes, so the sql statement would fail.

SELECT MAX query returns only 1 variable + codeigniter

I use codeigniter and have an issue about SELECT MAX ... I couldnot find any solution at google search...
it looks like it returns only id :/ it's giving error for other columns of table :/
Appreciate helps, thanks!
Model:
function get_default()
{
$this->db->select_max('id');
$query = $this->db->getwhere('gallery', array('cat' => "1"));
if($query->num_rows() > 0) {
return $query->row_array(); //return the row as an associative array
}
}
Controller:
$default_img = $this->blabla_model->get_default();
$data['default_id'] = $default_img['id']; // it returns this
$data['default_name'] = $default_img['gname']; // it gives error for gname although it is at table
To achieve your goal, your desire SQL can look something like:
SELECT *
FROM gallery
WHERE cat = '1'
ORDER BY id
LIMIT 1
And to utilise CodeIgniter database class:
$this->db->select('*');
$this->db->where('cat', '1');
$this->db->order_by('id', 'DESC');
$this->db->limit(1);
$query = $this->db->get('gallery');
That is correct: select_max returns only the value, and no other column. From the specs:
$this->db->select_max('age');
$query = $this->db->get('members');
// Produces: SELECT MAX(age) as age FROM members
You may want to read the value first, and run another query.
For an id, you can also use $id = $this->db->insert_id();
See also: http://www.hostfree.com/user_guide/database/active_record.html#select
CodeIgniter will select * if nothing else is selected. By setting select_max() you are populating the select property and therefore saying you ONLY want that value.
To solve this, just combine select_max() and select():
$this->db->select('somefield, another_field');
$this->db->select_max('age');
or even:
$this->db->select('sometable.*', FALSE);
$this->db->select_max('age');
Should do the trick.
It should be noted that you may of course also utilize your own "custom" sql statements in CodeIgniter, you're not limited to the active record sql functions you've outlined thus far. Another active record function that CodeIgniter provides is $this->db->query(); Which allows you to submit your own SQL queries (including variables) like so:
function foo_bar()
{
$cat = 1;
$limit = 1;
$sql = "
SELECT *
FROM gallery
WHERE cat = $cat
ORDER BY id
LIMIT $limit
";
$data['query'] = $this->db->query($sql);
return $data['query'];
}
Recently I have been utilizing this quite a bit as I've been doing some queries that are difficult (if not annoying or impossible) to pull off with CI's explicit active record functions.
I realize you may know this already, just thought it would help to include for posterity.
2 helpful links are:
http://codeigniter.com/user_guide/database/results.html
http://codeigniter.com/user_guide/database/examples.html