CakePHP 3 find() with order foreach each row - php

Man, I don’t know why this isn’t working, i’m following the Manuel verbatim.
I have a ProductStyles Table that has an order column. Suppose i have 5 rows. And I delete number 3. I want to find all rows matching the product id and iterate through each one of them replacing the order # incrementially.
Productstyle Table
id - product_id - order
My first step is to just fetch all the rows matching product ID in order so i can do a foreach but I keep get SQL errors. Honestly I don’t know SQL that well other than the basic select.
$query = $this->ProductStyles->find()
->where(['product_id'=> 1 ])
->order(['order' => 'ASC'])
;
//debug($query);
//debug( $query->all() ); //this throws an error
Error Message:
Error: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'order ASC' at line 1
SQL:
//SELECT ProductStyles.id AS `ProductStyles__id`, //ProductStyles.product_id AS
//`ProductStyles__product_id`, ProductStyles.style_id AS //`ProductStyles__style_id`,
//ProductStyles.order AS `ProductStyles__order` FROM product_styles ProductStyles
//WHERE product_id = :c0 ORDER BY order ASC
//die;
$i = 1;
foreach ($query as $row) {
//debug($row); die;
$ps= $this->ProductStyles->get($row->id);
//debug($ps);die;
$ps->order = $i;
$this->ProductStyles->patchEntity($ps,['order'=> $i]);
$this->ProductStyles->save($ps);
$i++;
}

order is a reservered word, and is not allowed to be used in an unquoted (in this case non-backticked) fashion, it would need to be used in the form of `order`
See
https://dev.mysql.com/doc/refman/5.7/en/keywords.html
https://dev.mysql.com/doc/refman/5.7/en/identifiers.html
I would suggest to change the column name, that's the easiest, and non-performance affecting fix. Another option would be to enable automatic identifier quoting, this will however affect the performance, and cannot be applied everywhere, see
Cookbook > Database Access & ORM > Database Basics > Identifier Quoting

order is a reserved keyword in SQL, so, if you want to use as a column name, you need to use quotes, like this:
SELECT * FROM table ORDER BY `order` ASC
As you can see in the error, is not being quoted.
Maybe you have to use $this->Model->query() and write the query manually.
Another solution is change the "order" column to another name.
Hope this helps.

Related

count of items from another table for each row in table

I have a list of user-profiles when I have this query. I want to retrieve nr of followers for each (every) user, but I only get one row result from query (there are a lot of users)
$this->db->select('up.name, up.id, up.image, up.name_id, up.created, COUNT(followers.user_id) as followed_by_count');
$this->db->join('user_profiles up', 'u.id = up.user_id', 'left');
$this->db->join('followers', 'up.user_id = followers.user_id', 'left');
//Something like this? (It doesn't work)
//$this->db->group_by('COUNT(followers.user_id) as followed_by_count');
//When tried this I get:
//"You have an error in your SQL syntax; check the manual that corresponds to your
//MySQL server version for the right syntax to use near 'as followed_by_count"
$this->db->order_by('up.created', 'DESC');
I guess I should use group by in some way? The query works when not using followers-table. It also works when not using group_by but I obviously don't get the count(s) I want then.
Change
$this->db->group_by('COUNT(followers.user_id) as followed_by_count');
To
$this->db->group_by('u.id');
Note : This code given as per your given code and assume that your code is syntactically right.

combine columns into one column mysql

I would like to combine two columns in one column as Fullname, and for that I have written the following code:
$this->db->select('CONCAT(first_name," ",last_name) AS FullName');
$this->db->from('customer');
$this->db->where('user_id',1);
$query = $this->db->get();
return $query->result_array();
The resulting query would be:
SELECT CONCAT(first_name," ",last_name) AS FullName
FROM customer
WHERE user_id = 1
but when i execute the above code it gives me:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM (customer) WHERE user_id = '1' at line 2
I have also tried with concat_ws group_concat but not able to get it work. Can anyone see what I'm doing wrong?
By default, CI tries to escape what you pass to db->select() (in case you were passing in user-generated values). You can disable this feature by passing false as a second argument.
$this->db->select('CONCAT(first_name," ",last_name) AS FullName', false);
I have been through this before with CI, in my case CI was wrongly creating the query, for example putting simgle quotes where they shouldn't be.
My advice create the query yourself and run it, you could be surprise :P

Sphinx RT Index and SphinxQL Query

We are deploying the RT index in our architecture. But we need some clarification and some difficulties faced during the deployment.
Schema defined in Index:
index logtable
{
type = rt
path = /usr/local/sphinx20/var/data/logtable
rt_attr_string = TransactionId
rt_attr_uint = CustomerId
rt_attr_timestamp = DateOfTransaction
rt_attr_string = CustomerFeedback
rt_field = TransactionType
}
Faced Problem
Question 1:
How we can get the count() query result in SPHINXQL. Because its important for us, based on customer count we have to take it to show in our application.
Example below,
Query - select count(*) from logtable where CustomerId='871';
In SphinxQL - We didnt get this result and getting the following error.ERROR 1064 (42000): index logtable: invalid schema: Count(*) or #count is queried, but not available in the schema.
Question 2:
i declared as a STRING attribute in conf for the field of "TransactionId", but i cant able to retrieve the records if that fields use in where condition.
Example below,
select * from logtable where TransactionId='TRA23454';
Following error i am getting,
ERROR 1064 (42000): sphinxql: syntax error, unexpected $undefined, expecting CONST_INT or CONST_FLOAT or '-' near '"TRA23454"'
Please help us to close these issues if knows.
Kumaran
select * from logtable where TransactionId='TRA23454';
Answer :
select * from logtable where MATCH('#TransactionId TRA23454')
In first example instead of count(*) you need to use 'show meta;' query after search query, it will contain total_count field.
select id from logtable where CustomerId='871';
show meta;
In the second example string attributes can't be used in WHERE, ORDER or GROUP clauses.
Actually you need to convert TransactionId into integer and use integer attribute. It is quite simple to do using crc32 mysql function.

CodeIgniter inserting apostrophes in to database query

I have a bit of a strange problem that has been baffling me. All I am trying to do is run a query on a database table but for some reason, CodeIgniter is putting apostrophes into the query which is subsequently breaking the page.
My code looks like this:
$this->db->select("SUBSTRING(body,5)");
$this->db->order_by("date", "desc");
$this->data['query'] = $this->db->get_where('blog-entries', array('status' => 'P'), 3);
But I get an error on this page:
Error Number: 1064
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM (`blog-entries`) WHERE `status` = 'P' ORDER BY `date` desc LIMIT 3' at line 2
The query is actually being run as:
SELECT SUBSTRING(body, `5)` FROM (`blog-entries`) WHERE `status` = 'P' ORDER BY `date` desc LIMIT 3
As you can see for some reason apostrophes have been added around the number 5 within the substring. If I remove the substring then everything works and if I remove the apostrophes and run the query directly on my db it also works.
Has any got any ideas as to why this may be happening or have a solution?
Your help would be greatly appreciated.
Many thanks,
G.
Use this:
$this->db->select("SUBSTRING(body,5)", FALSE);
As a default, Codeigniter tries to add back-ticks where it thinks is relevant. Sometimes it adds them where it shouldn't. Passing FALSE as the second parameter prevents it from doing this.

SQL Syntax Error when using primary key with WHERE

I am trying to use UPDATE with my MySQL-Database. I use the following SQL code:
$sql = "UPDATE ToDo
SET Checked = -1
WHERE Index = 1";
When I use this code i get the following error message: "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Index = 1' at line 3"
But when I use
$sql = "UPDATE ToDo
SET Checked = -1
WHERE Text = 'asdf'";
Everything works.
My database has one table named "ToDo" with 3 collumns: Index(int, primary key, auto_increment), Checked(bool) and Text(text).
Can't you "WHERE" a primary key or did i forget something else?
Hope you can help me.
Try adding the backticks:
UPDATE ToDo
SET `Checked` = -1
WHERE `Index` = 1";
Index is a reserved word :
http://dev.mysql.com/doc/refman/5.0/en/reserved-words.html
index is a reserved word for MySQL. You need to esacpe the name by adding backticks like this:
$sql = "UPDATE ToDo
SET Checked = -1
WHERE `Index` = 'asdf'";
In order to make sure MySQL understands that you are talking about a column name and not the reserved word, you can always address the column name tablename.columnname.
In SELECT queries also using shortcuts is possible:
UPDATE ToDo SET ToDo.Checked = -1 WHERE ToDo.Index = 1
SELECT u.Index FROM users u
Also I would recommend not to use camel cases in tables and columns. This proved to be a source for errors and has no real benefit most of the time.
Boolean is 0 or 1, not -1. Try using 0 or 1 for Checked and let us know what happens.

Categories