CodeIgniter: Unknown column xxx in ‘where clause’ - activerecord

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.

Related

Getting invalid identifier SQL query

I am trying to execute next query:
MERGE INTO NOTIFICATION_OBJS p
USING (SELECT
:fcsNotif_id as doc_id,
:OKPD2_code as OKPD2_code,
:OKPD2_name as OKPD2_name,
:quantity_value as quantity,
:purchaseObject_price as price
FROM DUAL
) v
ON (p.doc_id=v.doc_id)
WHEN MATCHED THEN
UPDATE SET
p.OKPD2_code = v.OKPD2_code,
p.OKPD2_name = v.OKPD2_name,
p.quantity_value = v.quantity_value,
p.price = v.price
WHEN NOT MATCHED THEN
INSERT (p.doc_id, p.OKPD2_code, p.OKPD2_name, p.quantity_value, p.price)
VALUES(v.doc_id, v.OKPD2_code, v.OKPD2_name, v.quantity_value, v.price)
I am sending to bind method next dictionary:
{'OKPD2_code': '62.02.30.000', 'OKPD2_name': 'some text', 'purchaseObject_price': '20466982.25', 'quantity_value': '1', 'fcsNotif_id': '18941152'}
But I am getting error:
ORA-00904: "P"."OKPD2_NAME": invalid identifier
All other query with binding are working. Please help me to find error.
There's no OKPD2_NAME column in NOTIFICATION_OBJS table.
If you used double quotes while creating that table (and its columns), you should
recreate the table without double quotes, or
reference the table (and its columns that use mixed case) using double quotes again, specifying case EXACTLY as it was while creating the table
[EDIT, after the screenshot has been uploaded]
Column name really is created using mixed case, so you'll have to reference it exactly like that: "OKPD2_name" paying attention to double quotes and mixed case.
If you use "okpd2_name" or "okPD2_NAME" or anything but "OKPD2_name", it won't work. Once again: get rid of double quotes.

Why do I get "ORA-00932: inconsistent datatypes: expected - got -" when using COLLECT() in a prepared statement?

I am using this query with the Perl DBI:
SELECT c.change_id
, COLLECT(t.tag) AS the_tags
FROM changes c
LEFT JOIN tags t ON c.change_id = t.change_id
WHERE c.project = ?
GROUP BY c.change_id
The DBI uses OCI to prepare this statement, bind the value I pass, and get the results. But Oracle, for some reason, does not like it. The error output is:
ORA-00932: inconsistent datatypes: expected - got - (DBD ERROR: error possibly near <*> indicator at char 41 in '
SELECT c.change_id
, <*>COLLECT(t.tag) AS the_tags
FROM changes c
LEFT JOIN tags t ON c.change_id = t.change_id
WHERE c.project = :p1
GROUP BY c.change_id
'
Not very informative. However, I can make this error go away not only by changing the call to COLLECT() also by replacing the placeholder with the actual value:
SELECT c.change_id
, COLLECT(t.tag) AS the_tags
FROM changes c
LEFT JOIN tags t ON c.change_id = t.change_id
WHERE c.project = 'tryoracle'
GROUP BY c.change_id
That version works perfectly. Why doesn't Oracle like the prepared statement with the COLLECT()?
In case it's any help, here is a trace of the OCI-related calls extracted via ora_verbose = 6 (h/t #bohica).
Finally got a solution to this issue, thanks to some digging by a user. The problem was not with the placeholder; why it worked without the placeholder on the VirtualBox image I have no idea. No, the issue was with the COLLECT(). Seems that both the values being collected need to be cast to a specific type, and the resulting array also needs to be cast to a pre-defined array data type. Just so happens that my code has a custom array type:
CREATE TYPE sqitch_array AS varray(1024) OF VARCHAR2(512);
So I'm able to get the query to work by casting the COLLECT() like so:
CAST(COLLECT(CAST(t.tags as VARCHAR2(512))) AS sqitch_array)

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

Issue with where clause in active record class

$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;

Resources