Sphinx RT Index and SphinxQL Query - php

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.

Related

How to Translate Codeigniter Pre Formatted Query Into an Original Mysql Query (e.g $this->db->select('table1.*,table2.*,table3.*'))

I have a website which is using a CodeIgniter framework and almost using CodeIgniter's preformatted query class in every request to process data from database built by my ex coworker.
One of the example is like this:
function tampilkan_data(){
$this->db->select('barang.*,barang_keluar.*,barang_masuk.*');
$this->db->from('barang');
$this->db->join('barang_keluar', 'barang.id_barang=barang_keluar.id_barang','left');
$this->db->join('barang_masuk', 'barang.id_barang=barang_masuk.id_barang','left');
$this->db->order_by('barang.id_barang','asc');
$this->db->order_by('barang.kode_barang','asc');
$this->db->where('barang.status','0');
return $query = $this->db->get()->result();
}
I want to change the result from that query, but in order to understand it first I have to translate it into an original MySQL query. Attempted to do this:
SELECT `barang`.*, `barang_keluar`.*, `barang_masuk`.*
FROM `barang` AS A
LEFT JOIN `barang_keluar` AS B ON A.id_barang = B.id_barang
LEFT JOIN `barang_masuk` AS C ON A.id_barang = C.id_barang
ORDER BY A.id_barang ASC, A.kode_barang ASC
WHERE A.status = 0
But I got this error
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 'WHERE A.status = 0 LIMIT 0, 25' at line 6
I tried to remove the WHERE A.status = 0 to see which is wrong from my code the I got this error
1051 - Unknown table 'barang'
I thought the problem is in the line SELECT barang.*, barang_keluar.*, barang_masuk.*, because I didn't really know how to write it in an MySQL original formatted.
I already searched for this topic and I even tried to write the query straight to the search bar but I didn't find the right approach according to my case.
Hope someone can help
You can simply print your query, Then you can see your query in original sql format.
function tampilkan_data(){
$this->db->select('barang.*,barang_keluar.*,barang_masuk.*');
$this->db->from('barang');
$this->db->join('barang_keluar', 'barang.id_barang=barang_keluar.id_barang','left');
$this->db->join('barang_masuk', 'barang.id_barang=barang_masuk.id_barang','left');
$this->db->order_by('barang.id_barang','asc');
$this->db->order_by('barang.kode_barang','asc');
$this->db->where('barang.status','0');
$query = $this->db->get()->result(); // notice that i have removed the return keyword
echo $this->db->last_query(); // This will print your query directly on the screen.
}
But the error which you are getting is -> You don't have a table named barang.
Make sure that the table exists.
Hope It Helps...
If you want to look at the query string generated by the CI Query builder then you can log this method $this->db->last_query() which will give the last SQL query as string executed by it.
Your query is almost ok. But you will have to change it on order by. Because u have used asc more than once, that is not supported by mysql as well. You need to modify your query like below
SELECT A.*, B.*, C.*
FROM barang AS A
LEFT JOIN barang_keluar AS B ON A.id_barang = B.id_barang
LEFT JOIN barang_masuk AS C ON A.id_barang = C.id_barang
WHERE A.status = 0 ORDER BY A.id_barang, A.kode_barang ASC
Now be confirm that you have table barang in your database and try again. If you face another sql problem just reply with your screenshot of code snippet here.

serverfireteam/panel validation:how to check for unique value in column

I'm using Laravel with serverfireteam/panel and I need that the validation checks for a unique value in column.
I tested this:
$this->edit->add('nr','Nummer','text')->rule('required')->rule('unique:nr');
result Query:
SQL: select count(*) as aggregate from `nr` where `nr` = 22
and this:
$this->edit->add('nr', 'Nummer','text')->rule('required')->rule('unique:.kunden nr');
which results in:
(SQL: select count(*) as aggregate from `kunden nr` where `nr` = 22)
Is it possible to check for uniqueness with rules in serverfireteam/panel and how does it work?
I found the solution for the problem. It's similar Syntax used like in laravel's default Syntax https://laravel.com/docs/5.1/validation.
But here you have always to add the tablename:
->rule('unique:tablename,columnname')
for example:
$this->edit->add('nr', 'Nummer','text')->rule('required')->rule('unique:kunden,nr');

Dynamic SQL Error 804 Incorrect values within SQLDA structure

I'm getting this dynamic sql warning after trying to fetch results from this query:
Warning: ibase_fetch_assoc(): Dynamic SQL Error SQL error code = -804 Incorrect values within SQLDA structure
SELECT VOORRAADAUTO.*, AUTOMERK.*, VOORRAADAUTO.OMSCHRIJVING as uitvoeringnaam
FROM VOORRAADAUTO
LEFT JOIN AUTOMERK ON AUTOMERK.AUTOMERKID = VOORRAADAUTO.AUTOMERKID
WHERE VOORRAADAUTO.SOORTVOORRAADSTATUSID = 2 AND VOORRAADAUTO.TOTAALCONSUMENT > 0 ORDER BY AUTOMERK.OMSCHRIJVING DESC, VOORRAADAUTO.TOTAALCONSUMENT, VOORRAADAUTO.MODELOMSCHRIJVING;
And this php code:
$p_sql = ibase_prepare($sql);
$rs = ibase_execute($p_sql);
while($row = ibase_fetch_assoc($rs)){
$auto = new auto($row);
$this->list[] = $auto;
}
How come there are incorrect values? And how do you solve this problem?
You can always try to run the sql direct on the database.
Because the Sql query looks ok, I can only think maybe there is a typo in a field name or doesn't return rows. Or the where fields aren't numeric
Also may I suggest use alias instead of full table name, that help to read the query.
SELECT V.*, A.*, V.OMSCHRIJVING as uitvoeringnaam
FROM VOORRAADAUTO V
LEFT JOIN AUTOMERK A
ON A.AUTOMERKID = V.AUTOMERKID
WHERE V.SOORTVOORRAADSTATUSID = 2 AND V.TOTAALCONSUMENT > 0
ORDER BY A.OMSCHRIJVING DESC, V.TOTAALCONSUMENT, V.MODELOMSCHRIJVING;
Don't know if you solved it already, but i had the same error with a simple query like:
SELECT * FROM "any_Table" WHERE "id"=1
It worked for me after i replace the * with the column name:
SELECT "id", "Name" FROM "any_table" WHERE "id"=1
I think it has something to do with the interbase driver, i found this:
Bug report
It appears that the php interbase client can't handle boolean fields, after i had changed the boolean field in a integer the select * works.
I'm using XAMPP, PHP Version 5.6.15, with interbase XE7 on windows and used gds32.dll from the interbase install (12.0.4.357).

CakePHP 3 find() with order foreach each row

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.

Having an issue using datatable library with codeigniter

I already posted a question regarding this issue on another post but I want to try to be more specific here
So I have the following query here using codeigniter with a library from https://github.com/IgnitedDatatables/Ignited-Datatables/wiki/Function-Reference
<?php
public function GetQuery(){
$this->datatables->select('tablessc.Name As region,p.name As name,tabled.test As test,
MAX(CASE WHEN p.id= p.cid and flavor = 2 THEN \'Pass\' ELSE \'Fail\' end) as \'Pass\'
')
->from('drinks p');
$this->datatables->join('tableb ', 'tableb.id=p.pid','inner');
$this->datatables->join('tablec','tablec.TerritoryId=tablec.TerritoryId','inner');
$this->datatables->join('tabled','tablec.AccountId=tablec.AccountId','inner');
$this->datatables->join('tables','d.AccountId = tabless.AccountId ','inner');
$this->datatables->join('tablessc','tablesc.Code = p.region and sc.CodeGroup =\'Region\'','inner');
$this->datatables->where('region >','0');
$this->datatables->where('p.location','0');
$this->datatables->group_by('tablessc.Name');
$this->datatables->group_by('p.id');
$this->datatables->group_by('p.name');
$this->datatables->group_by('atabled.test');
echo $this->datatables->generate();
}
?>
Ok so if I run this query on microsoft sql I get no error and I get the results I want, but if i call this function from a page it will give me an error
Error Number: 42000
[Microsoft][SQL Server Native Client 10.0][SQL Server]Column 'drinks.region' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause
SELECT * FROM drinks p INNER JOIN.....
Just to take a note here why is the error showing the sql doing a select *
I tried taking the max aggregate function out and it still doing the same error.
THe only way to get rid of this error is to take out the aggregate function MAX and the group by clause. Which is no the query I want.Any one else have experience this problem with the library? Thank you
In SQL server all columns used in the select column must appear in group_by clause unless the column is used in an aggregate function.
The 'get_total_results' function in datatable library produces 'SELECT * FROM table_name GROUP_BY column_name ' query. So the 'drinks.region' column which was not actually selected in your query is appearing in the error message.
As a fix try adding
if(count($this->group_by) > 0)
{
$this->ci->db->select($this->columns);
}
inside the get_total_results() function in Datatable.php file

Categories