Zend_Db problem whith the placeholders from SQL string - zend-db

I have the following SQL
SELECT i_id AS "entity_id", "entity_1" AS "type"
FROM tbl_extensions WHERE ext = 50
which returns me the result and an additional column "type" with the value "entity_1"
to gain the same with Zend_Db I've tried:
$db->fetchAll($db->select()
->from('tbl_extensions',
array('entity_id' => 'i_id',
'type' => 'entity_1'))
->where('ext = ?', 50)));
But I have the following error:
Message: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'tbl_extensions.type' in 'field list'
It looks like Zend tries to find a column instead of creating it within the result.
Could anyone help me with it?

easiest solution would be to use Zend_Db_Expr.
$db->fetchAll($db->select()
->from('tbl_extensions',
array(
'entity_id' => 'i_id',
new Zend_Db_Expr('"entity_1" AS "type"'),
)
)
->where('ext = ?', 50));

Related

Linq2DB can't translate a mapped column in Where clause

I'm working with a legacy Oracle database that has a column on a table which stores boolean values as 'Y' or 'N' characters.
I have mapped/converted this column out like so:
MappingSchema.Default.SetConverter<char, bool>(ConvertToBoolean);
MappingSchema.Default.SetConverter<bool, char>(ConvertToChar);
ConvertToBoolean & ConvertToChar are simply functions that map between the types.
Here's the field:
private char hasDog;
[Column("HAS_DOG")]
public bool HasDog
{
get => ConvertToBoolean(hasDog);
set => hasDog = ConvertToChar(value);
}
This has worked well for simply retrieving data, however, it seems the translation of the following:
var humanQuery = (from human in database.Humans
join vetVisit in database.VetVisits on human.Identifier equals vetVisit.Identifier
select new HumanModel(
human.Identifier
human.Name,
human.HasDog,
vetVisit.Date,
vetVisit.Year,
vetVisit.PaymentDue
));
// humanQuery is filtered by year here
var query = from vetVisits in database.VetVisits
select new VetPaymentModel(
(humanQuery).First().Year,
(humanQuery).Where(q => q.HasDog).Sum(q => q.PaymentDue), -- These 2 lines aren't correctly translated to Y/N
(humanQuery).Where(q => !q.HasDog).Sum(q => q.PaymentDue)
);
As pointed out above, the .Where clause here doesn't translate the boolean comparison of HasDog being true/false to the relevant Y/N values, but instead a 0/1 and results in the error
ORA-01722: invalid number
Is there any way to handle this case? I'd like the generated SQL to check that HAS_DOG = 'Y' for instance with the specified Where clause :)
Notes
I'm not using EntityFramework here, the application module that this query exists in doesn't use EF/EFCore
You can define new mapping schema for your particular DataConnection:
var ms = new MappingSchema();
builder = ms.GetFluentMappingBuilder();
builder.Entity<Human>()
.Property(e => e.HasDog)
.HasConversion(v => v ? 'Y' : 'N', p => p == 'Y');
Create this schema ONCE and use when creating DataConnection

Yii2 filter related model

I have a Sale model, that contains a property_id FK to Property model.
On Property model, there is a field office_id.
The Sale controller contains a partial _search view that I am using to try filter via the office_id.
In search function, I first set the relations to find():
$query = sale::find()->with([
'property',
'listerSaleStaff',
'listerSaleStaff.staff',
'sellerSaleStaff',
'sellerSaleStaff.staff',
]);
The filter clause:
$query->andFilterWhere(['=', 'property.office_id', $params['SaleSearch']['office']]);
where $params['SaleSearch']['office'] does in fact contain the correct office_id
I'm getting PDOException:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'property.office_id' in 'where clause'
The SQL being executed was: SELECT COUNT(*) FROM `sale` WHERE ((`settle_date` >= '2016-07-03') AND (`settle_date` <= '2016-07-31')) AND (`property`.`office_id` = '5')
Error Info: Array
(
[0] => 42S22
[1] => 1054
[2] => Unknown column 'property.office_id' in 'where clause'
Property model does contain relationship:
public function getOffice()
{
return $this->hasOne(Office::className(), ['office_id' => 'office_id']);
}
What am i missing ?
I think you should set the join for search
$query->joinWith(['office' => function ($q) use ($params['SaleSearch']['office']]) {
$q->andFilterWhere(['=', 'property.office_id', $params['SaleSearch']['office']]);
}]);

Perl SQL::Parser table alias substitution: works for SELECT column names but not for WHERE column names

I'm trying to parse some SQL queries stored in a log database -- I don't want to submit them to a SQL database, just to extract the fields used in the SELECT and WHERE clause.
I've been fiddling with several SQL parsers in Java, Python and Perl. The one that seems to work better for my problem are SQL::Parser and SQL::Statement. With those I was able to write the following code:
#!/usr/bin/perl
use strict;
use SQL::Parser;
use SQL::Statement;
use Data::Dumper;
my $sql = "SELECT sl.plate,sp.fehadop FROM sppLines AS sl ".
"JOIN sppParams AS sp ON sl.specobjid = sp.specobjid ".
"WHERE fehadop < -3.5 ";
my $parser = SQL::Parser->new();
my $stmt = SQL::Statement->new($sql,$parser);
printf("COMMAND [%s]\n",$stmt->command);
printf("COLUMNS \n");
my #columns = #{$stmt->column_defs()};
foreach my $column ( #columns)
{
print " ".$column->{value}."\n";
}
printf("TABLES \n");
my #tables = $stmt->tables();
foreach my $table ( #tables)
{
print " ".$table->{name}."\n";
}
printf("WHERE COLUMNS\n");
my $where_hash = $stmt->where_hash();
print Dumper($where_hash);
Sorry if it is too long, it is the smallest, self-contained example I could devise.
The output of this code is:
COMMAND [SELECT]
COLUMNS
spplines.plate
sppparams.fehadop
TABLES
spplines
sppparams
WHERE COLUMNS
$VAR1 = {
'arg1' => {
'value' => 'fehadop',
'type' => 'column',
'fullorg' => 'fehadop'
},
'op' => '<',
'nots' => {},
'arg2' => {
'str' => '-?0?',
'fullorg' => '-3.5',
'name' => 'numeric_exp',
'value' => [
{
'fullorg' => '3.5',
'value' => '3.5',
'type' => 'number'
}
],
'type' => 'function'
},
'neg' => 0
};
The parser returns the name of columns (obtained through a call to $stmt->column_defs()) already renamed with the real tables names (e.g. spplines.plate instead of s1.plate) -- this is what I want.
I also want the names of the columns used in the WHERE clause.
I already know how to recursively parse the results of $stmt->where_hash() (didn't include the code to make the post clear), but even from dumping its contents I can see that the column names are not associated with the tables.
I would like to ensure that the columns names in the WHERE clause are also preceded by the tables name. After parsing the results of $stmt->where_hash() I would get sppparams.fehadop instead of fehadop.
Is this possible with SQL::Parser?
Thanks
(big edit -- tried to make the question clearer)
Since SQL::Statement has an eval_where, I suspect there might be a better way, but you can try a function like this:
get_column($stmt->column_defs(), $where_hash->{arg1});
sub get_column {
my ($columns, $arg) = #_;
return $arg->{fullorg} if ($arg->{type} ne 'column');
foreach my $col (#$columns) {
return $col->{value} if ($col->{fullorg} eq $arg->{fullorg});
my ($name) = ( $col->{fullorg} =~ /([^.]+)$/);
return $col->{value} if ($name eq $arg->{fullorg});
}
return $arg->{fullorg};
}

CGridView Parse error in when i try convert data

Error in CGridView Yii, what i need to do, what fix it:
Parse error: syntax error, unexpected T_STRING in Z:\home\kaskad\www\framework\base\CComponent.php(612) : eval()'d code on line 1
'date'=>array(
'value' => $this->rus_date("j F Y H:i ", $data->date),
),
You can reference the controller in the value expression as follows using $this->grid->controller:
'date'=>array(
'value' => '$this->grid->controller->rus_date("j F Y H:i ", $data->date)',
),

How to use IFNULL with yii CDbCriteria?

In yii, i have a CDbCriteria with select property as:
$criteria->select = "IFNULL(t.cccid,'Default')";
That is I want to return 'Default' if t.cccid is NULL. Else value of t.cccid should be returned/
The problem is that IFNULL is not being recognized. I get error as:
trying to select an invalid column "'Default')"
I have also tried:
$criteria->select = "IFNULL(t.cccid,'Default') as cccid";
and then i get syntax error.
Can anyone help me on how to use IFNULL in $criteria->select?
Use of CDbExpression would help you here
$criteria->select = new CDbExpression("IFNULL(t.cccid,'Default') cccid");
or (to select * , or other columns, use array )
$criteria->select = array(
'*',
new CDbExpression("IFNULL(t.cccid,'Default') cccid"),
);