Issue with where clause in active record class - codeigniter

$params['title'] is a string and $params['feed'] is an integer. Column's 'title' type is varchar and column's 'feed' type is integer. The PHP code is:
$this->db->where('title', $params['title']);
$this->db->where('feed', $params['feed']);
$query = $this->db->get('news');
So everything should be fine, BUT...
A Database Error Occurred
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 'riots: intense anger after deaths of three young men AND `feed` = '1'' at line 3
SELECT * FROM (`news`) WHERE `title` = Birmingham riots: intense anger after deaths of three young men AND `feed` = '1'
Filename: C:\path\system\database\DB_driver.php
Line Number: 330
Of course, it's obvious why an error occurred. Is there any way to fix it (apart from not using active record class)? Looked at CI's documentation, but have no idea why this problem occurred.
EDIT
Solved by changing to
$this->db->where('title', (string) $params['title']);
And other clause accordingly. And now have a bunch of identical errors in other models. Well, I guess the only solution is to add var type everywhere manually.

It looks like this SimpleXML class's title property isn't a string.
You could simply cast it to a string as soon as you get it, instead of waiting until you do the insert.
data['title'] = (string) $item->title;

Related

Wierd bug in CodeIgniter when I queried two tables with relationship... o_O

So I got a wierd bug (or maybe I'm just stupid), when I runs an active record query. Take a look at this:
$results = $this->db->
select('cd.casino_name, cd.casino_opened, cd.casino_latitude, cd.casino_longitude')->
from('casino_data as cd, casino_cities as cc')->
where('cd.city_id',$city_id)->
where('cd.city_id=cc.city_id')->
get()->result_array();
Then I got that:
Error Number: 1054
Unknown column 'cd.city_id=cc.city_id' in 'where clause'
SELECT `cd`.`casino_name`, `cd`.`casino_opened`, `cd`.`casino_latitude`, `cd`.`casino_longitude`
FROM (`m_casino_data` as cd, `m_casino_cities` as cc)
WHERE `cd`.`city_id` = 1
AND `cd`.`city_id=cc`.`city_id`
Filename: httpdocs/_dev/libraries/Test.php
Line Number: 649
Sh*t happened... Or in v2.0 CI has been changed something in the DB class?
help plz...thx
The problem is there with the where clause
$results = $this->db->
select('cd.casino_name, cd.casino_opened, cd.casino_latitude, cd.casino_longitude')->
from('casino_data as cd, casino_cities as cc')->
where('cd.city_id',$city_id)->
where('cd.city_id','cc.city_id')->//this would produce WHERE cd.city_id = cc.city_id
get()->result_array();
CodeIgniter's AR protecting works poorly sometimes. In this cases I think you should use an optional parameter FALSE to avoid autoprotecting. But not all function accepts this parameter - but where yes!
$this->db->where() accepts an optional third parameter. If you set it to FALSE, CodeIgniter will not try to protect your field or table names with backticks.
See documentation (you can find near 4. Custom string).

ActiveRecord search returns 'Syntax error or access violation' error

In my Yii application, I have a model that represents siteconfig table and have four columns:
integer config_id,
string key,
string value,
string update_time.
I created a model using Gii (to ensure that I will not make any mistakes). I don't publish entire code here, cause this is 100% unmodified by me, standard model code generated by Gii. Since my problem is related to search, I only publish important part of generated code (the search() method):
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('config_id',$this->config_id);
$criteria->compare('key',$this->key,true);
$criteria->compare('value',$this->value,true);
$criteria->compare('update_time',$this->update_time,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
I'm trying to use generated model in normal Yii ActiveRecord search like that:
$etona = new SiteConfigurationRecord();
$crit = new CDbCriteria();
$crit->select = "value";
$crit->condition = "key=:key";
$crit->params = array(":key"=>"sitename");
$etona = $etona->find($crit);
But, instead of getting expected search results, a strange (for me) error occurs:
CDbCommand failed to execute the SQL statement: 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 'key='sitename' LIMIT 1' at line 1.
The SQL statement executed was: SELECT value FROM siteconfig t
WHERE key=:key LIMIT 1
Where did I go wrong?
You used key for column name, which is a reserved word in MySQL. Yii uses table alias in queries, but does not take any special care in case of reserverd word used as columns names. So, you have to take care of this by yourself.
For example:
$etona = new SiteConfigurationRecord();
$crit = new CDbCriteria();
$crit->select = "value";
$crit->condition = "t.key=:key"; // 't' is default alias
$crit->params = array(":key"=>"sitename");
$etona = $etona->find($crit);
This should solve your problem.
As #Dmitry explained, SQL doesn't allow you to use the column name key. The Yii call in the code in your answer works because Yii performs parameter binding automatically, using names other than reserved words for the parameters. And it also uses fully-qualified column names (prefixes all column name references with <tablename>., regardless of what invalid column name (reserved words) you pass the findByAttributes method.
now it works.. ^^
i just use this code...
$etona = SiteConfigurationRecord::model()->findByAttributes(array('key'=>'sitename'));
maybe i need to study activerecord more somehow...
but still i don't know why the code above doesn't work

LINQ 2 Entities-query is not working, but why?

everyone! ))
Here is code.
var existingEntities = (from record in globalOne.serviceContext.records_out
where record.timestamp.Date == DateTime.Now.Date
select record ).ToList();
It doesn't work.
Another code:
var existingEntities = (from record in globalOne.serviceContext.records_out
where record.timestamp.Day == DateTime.Now.Day
select record ).ToList();
It does work.
So, problem id in next string:
where record.timestamp.**Date** == DateTime.Now.Date
also won't do
where record.timestamp.Date.Equals(DateTime.Now.Date)
But why? I have no clue. "Timestamp" field is dateTime field in MS SQL SERVER.
And - there is NO records in table.
And I almost forgot - what does it mean - "doesn't work".
App just will not reach the breakpoint after that query(first), without any error, without anything.
Thanks.
You can call record.timestamp.Date because EF can't convert it to required expression tree (then convert it to sql command). In fact EF supports limited number of functions and properties, But for DateTime, EF has some good Canonical functions. You can use them in your case, e.g you can use Day(),Month(),Year() functions to solve your problem (see the link).

CodeIgniter: Unknown column xxx in ‘where clause’

I am working on a bug(?) for a few hours now, but couln’t fix it.
This is my code:
if(!$this->db->get_where('merken',array('m_merken' => $brand))->count_all_results()){
$insetData = array('m_name' => $brand);
$this->db->insert('merken', $insetData);
}
$brand contains ‘Acer’ in this preview.
A Database Error Occurred
Error Number: 1054
Unknown column ‘Acer’ in ‘where clause’
SELECT * FROM (`merken`) WHERE `m_name` = Acer
I want to check if it already exists, but it won’t work very well.
Without quotes, your statement:
SELECT * FROM (`merken`) WHERE `m_name` = Acer
Acer refers to a column-name. If your intent is a string literal, put it in single-quotes, as in:
SELECT * FROM (`merken`) WHERE `m_name` = 'Acer'
Also, as a matter of good programming practice, avoid SELECT *, better to SELECT each column you want to return, even if the list is lengthy.
-- EDIT --
I suspect I'm missing the point... the SQL is generated. Two things to check:
Is m_name correctly declared as a string/varchar/char field?
Failing that, try literally setting the brand name to 'Acer', with the quote marks. I doubt this is a reasonable solution, though.

Entity Framework - "Unable to create a constant value of type 'Closure type'..." error

Why do I get the error:
Unable to create a constant value of type 'Closure type'. Only
primitive types (for instance Int32, String and Guid) are supported in
this context.
When I try to enumerate the following Linq query?
IEnumerable<string> searchList = GetSearchList();
using (HREntities entities = new HREntities())
{
var myList = from person in entities.vSearchPeople
where upperSearchList.All( (person.FirstName + person.LastName) .Contains).ToList();
}
Update:
If I try the following just to try to isolate the problem, I get the same error:
where upperSearchList.All(arg => arg == arg)
So it looks like the problem is with the All method, right? Any suggestions?
It looks like you're trying to do the equivalent of a "WHERE...IN" condition. Check out How to write 'WHERE IN' style queries using LINQ to Entities for an example of how to do that type of query with LINQ to Entities.
Also, I think the error message is particularly unhelpful in this case because .Contains is not followed by parentheses, which causes the compiler to recognize the whole predicate as a lambda expression.
I've spent the last 6 months battling this limitation with EF 3.5 and while I'm not the smartest person in the world, I'm pretty sure I have something useful to offer on this topic.
The SQL generated by growing a 50 mile high tree of "OR style" expressions will result in a poor query execution plan. I'm dealing with a few million rows and the impact is substantial.
There is a little hack I found to do a SQL 'in' that helps if you are just looking for a bunch of entities by id:
private IEnumerable<Entity1> getByIds(IEnumerable<int> ids)
{
string idList = string.Join(",", ids.ToList().ConvertAll<string>(id => id.ToString()).ToArray());
return dbContext.Entity1.Where("it.pkIDColumn IN {" + idList + "}");
}
where pkIDColumn is your primary key id column name of your Entity1 table.
BUT KEEP READING!
This is fine, but it requires that I already have the ids of what I need to find. Sometimes I just want my expressions to reach into other relations and what I do have is criteria for those connected relations.
If I had more time I would try to represent this visually, but I don't so just study this sentence a moment: Consider a schema with a Person, GovernmentId, and GovernmentIdType tables. Andrew Tappert (Person) has two id cards (GovernmentId), one from Oregon (GovernmentIdType) and one from Washington (GovernmentIdType).
Now generate an edmx from it.
Now imagine you want to find all the people having a certain ID value, say 1234567.
This can be accomplished with a single database hit with this:
dbContext context = new dbContext();
string idValue = "1234567";
Expression<Func<Person,bool>> expr =
person => person.GovernmentID.Any(gid => gid.gi_value.Contains(idValue));
IEnumerable<Person> people = context.Person.AsQueryable().Where(expr);
Do you see the subquery here? The generated sql will use 'joins' instead of sub-queries, but the effect is the same. These days SQL server optimizes subqueries into joins under the covers anyway, but anyway...
The key to this working is the .Any inside the expression.
I have found the cause of the error (I am using Framework 4.5). The problem is, that EF a complex type, that is passed in the "Contains"-parameter, can not translate into an SQL query. EF can use in a SQL query only simple types such as int, string...
this.GetAll().Where(p => !assignedFunctions.Contains(p))
GetAll provides a list of objects with a complex type (for example: "Function"). So therefore, I would try here to receive an instance of this complex type in my SQL query, which naturally can not work!
If I can extract from my list, parameters which are suited to my search, I can use:
var idList = assignedFunctions.Select(f => f.FunctionId);
this.GetAll().Where(p => !idList.Contains(p.FunktionId))
Now EF no longer has the complex type "Function" to work, but eg with a simple type (long). And that works fine!
I got this error message when my array object used in the .All function is null
After I initialized the array object, (upperSearchList in your case), the error is gone
The error message was misleading in this case
where upperSearchList.All(arg => person.someproperty.StartsWith(arg)))

Resources