Dynamic operators in where clause in Informatica - sql

Is it possible to create dynamic sql operator in Informatica using SQL Transformation. For eg.
SELECT p.id
FROM products p
WHERE p.weight ?operator? '30'
where ?operator? can have values: <, > , =
or even: in, not in

The SQL Editor window of SQL Transform allows to use parameter binding (?parameter?) and string substitution (~string~). You need the latter:
SELECT p.id
FROM products p
WHERE p.weight ~operator~ '30'
This topic is described well in SQL Transformation > Query Mode chapter of the Transformation Guide.

One idea is to use a parameter for the whole condition, e.g. With this sample paramFile:
[s_m_test_source_param]
$$sq_param = Id = 1
Use $$sq_param value for Source Filter property on Source Qualifier. In your case youd need to set the $$sq_parameter in this way:
$$sq_param = p.weight > '30'
Obviously, this is not perfect solution you've been looking for.

Related

How to convert Sql inner query to Linq for sum of column

How to Convert this sql query to Linq.
select sum(OutstandingAmt)from IvfReceiptDetails where IvfReceiptId IN(select IvfReceiptId from IvfReceipts where PatientId = 'SI-49650')
I think it is easier to translate SQL using query comprehension syntax instead of lambda syntax.
General rules:
Translate inner queries into separate query variables
Translate SQL phrases in LINQ phrase order
Use table aliases as range variables, or if none, create range variables from table names
Translate IN to Contains
Translate SQL functions such as DISTINCT or SUM into function calls on the entire query.
Here is the code:
var IvfReceiptIds = from IvfReceipt in IvfReceipts
where IvfReceipt.PatientId = "SI-49650"
select IvfReceipt.IvfReceiptId;
var OutstandingAmtSum = (from IvfReceiptDetail in IvfReceiptDetails
where IvfReciptIds.Contains(IvfReceiptDetail.IvfReceiptId)
select IvfReceiptDetail.OutstandingAmt).Sum();
Try this, First get all IvfReceiptId in array based on your inner query used in where condition then check contains. Change name of your _context if it's different.
var arrIvfReceiptId = _context.IvfReceiptDetails.Where(p=>p.PatientId == "SI-49650").ToArray();
var sum = (from ird in _context.IvfReceiptDetails.Where(p=> arrIvfReceiptId.Contains(p.IvfReceiptId))
select OutstandingAmt).Sum();

"Circular reference caused by ..." error in Access SQL (but not in T-SQL)

I have the following SQL statement which returns the desired result in SQL Server 2012:
SELECT
S.ONOMA
, S.DIEY
, S.POLH
, S.TK
, S.IDIOT
, S.KODIKOS
, S.AFM
FROM
SYNERG AS S
INNER JOIN
(SELECT
G.AFM, MIN(KODIKOS) AS KODIKOS
FROM SYNERG AS G
WHERE LEN(ISNULL(AFM, '')) != 0
GROUP BY AFM) AS I ON S.KODIKOS = I.KODIKOS
ORDER BY
S.AFM
but when I run the same SQL statement in MS Access 2007 I get an error:
Circular reference caused by 'KODIKOS' in query definition's SELECT list.
Any help would be appreciated.
As explained in the link by HansUp:
The alias of a calculated field cannot be identical to any of the field names used to calculate the field.
This can be rather annoying (esp. if it is a field that is returned by the query), but there is no way around it.
So you need to change the alias, e.g.:
SELECT
S.ONOMA
, S.DIEY
, S.POLH
, S.TK
, S.IDIOT
, S.KODIKOS
, S.AFM
FROM
SYNERG AS S
INNER JOIN
(SELECT
G.AFM, MIN(KODIKOS) AS MinKODIKOS
FROM SYNERG AS G
WHERE LEN(Nz(AFM, '')) <> 0
GROUP BY AFM) AS I ON S.KODIKOS = I.MinKODIKOS
ORDER BY
S.AFM
Note also that an IsNull() function exists in Access, but has a different meaning (it takes one argument and returns a Boolean). The corresponding function is Nz()
And (thanks #HansUp), the unequal operator is <>, not !=. I always use <> in SQL Server too, no need to make things more complicated than necessary. :)

SQL regex and field

I want to change the query to return multiply values in extra_fields, how can I change the regex? Also I don't understand what extra_fields is - is it a field? If so why it is not called with the table prefix like i.extra_fields?
SELECT i.*,
CASE WHEN i.modified = 0 THEN i.created ELSE i.modified END AS lastChanged,
c.name AS categoryname,
c.id AS categoryid,
c.alias AS categoryalias,
c.params AS categoryparams
FROM #__k2_items AS i
LEFT JOIN #__k2_categories AS c ON c.id = i.catid
WHERE i.published = 1
AND i.access IN(1,1)
AND i.trash = 0
AND c.published = 1
AND c.access IN(1,1)
AND c.trash = 0
AND (i.publish_up = '0000-00-00 00:00:00'
OR i.publish_up <= '2013-06-12 22:45:19'
)
AND (i.publish_down = '0000-00-00 00:00:00'
OR i.publish_down >= '2013-06-12 22:45:19'
)
AND extra_fields REGEXP BINARY '(.*{"id":"2","value":\["[^\"]*1[^\"]*","[^\"]*2[^\"]*","[^\"]*3[^\"]*"\]}.*)'
ORDER BY i.id DESC
The extra_fields is a column of the #__k2_items table. The table qualifier can be omitted, because it is not ambiguous in this query. The column is JSON encoded. That is a serialization format used to store information which is not searchable by design. Applying a RegExp may work one day, but fail another day, since there is no guarantee for id preceeding value (as in your example).
The right way
The right way to filter this is to ignore the extra_fields condition in the SQL query an evaluate in the resultset instead. Example:
$rows = $db->loadObjectList('id');
foreach ($rows as $id => $row) {
$extra_fields = json_decode($row->extra_fields);
if ($extra_fields->id != 2) {
unset($rows[$id]);
}
}
The short way
If you can't change the database layout (which is true for extensions you want to keep updateable), you must split the condition into two, because there is no guarantee for a certain order of the subfields. For some reason, one day value may occur before id. So change your query to
...
AND extra_fields LIKE '%"id":"2"%'
AND extra_fields REGEXP BINARY '"value":\[("[^\"]*[123][^\"]*",?)+\]'
Prepare an intermediate table to hold the contents of extra_fields. Each extra_fields field will be converted into a series of records. Then do a join.
Create a trigger and cronjob to keep the temp table in sync.
Another way is to write UDF in Perl that will decode the field, but AFAIK it is not indexable in mysql.
Using an external search engine is out of scope.
Ok, i didnt want to change the db strucure, i gost some help and changed the regex intoAND extra_fields REGEXP BINARY '(.*{"id":"2","value":\[("[^\"]*[123][^\"]*",?)+\]}.*)'
and i got the right resaults
Thanks

Liferay DynamicQuery - xPath and Array comparison

My final goal is I want to get plid and portletId that can be display my article(or entry with any type if it is possible).
I have sql query that return me any portlet availble for display my article.
But when I have to use dynamicQuery to get the same results, I get problem with xPath and array comparison, please help!
SELECT * FROM portletpreferences pr
WHERE pr.preferences != '<portlet-preferences />' AND pr.ownerid = 0 AND pr.portletid ilike '%_INSTANCE_%' AND pr.plid IN(
SELECT layout.plid FROM layout
WHERE layout.type_ = 'portlet' AND layout.groupid = 19 AND layout.hidden_ is false)
AND pr.portletpreferencesid IN (
SELECT pr.portletpreferencesid FROM portletpreferences pr
WHERE 'true' = ANY(xpath('//preference[name="anyAssetType"]/value/text()', XMLPARSE(DOCUMENT pr.preferences))::text[])
OR (SELECT (array(SELECT id_ FROM journalstructure))::text[]) && xpath('//preference[name="classTypeIds"]/value/text()', XMLPARSE(DOCUMENT pr.preferences))::text[] )
If you are bent upon using this same query, then use this query directly with Custom-SQL in liferay by creating custom-finders instead of using DynamicQuery. That would give you a lot of flexibility in using any type of SQL query directly.
I don't think this query can be converted to DynamicQuery, but if you do manage to convert it then please do post it here :-)
DynamicQuery is very powerful, see e.g. my answer how to find layouts with specific JournalArticles. I think your requirement is similar to this one:
Liferay: How to find all Layouts with the specific JournalArticle in AssetPublisher portlets?

Formula Phone Call Calculation

I'm using the following statement to determine the correct prefix:
select *
from [lcsCDR].[dbo].[Phones] c
inner join [CallAnalysisDatabase].[dbo].[CallRates$] r
on r.Prefix COLLATE Latin1_General_CI_AI = SUBSTRING(c.PhoneUri,1,LEN(r.Prefix))
left join [CallAnalysisDatabase].[dbo].[CallRates$] r_anti
on r_anti.Prefix COLLATE Latin1_General_CI_AI = SUBSTRING(c.PhoneUri,1,LEN(r_anti.Prefix))
and LEN(r_anti.Prefix) > LEN(r.Prefix)
where r_anti.Prefix is null
Could you please give me an example for adding a formula integrated within this statement?
The 'Rate' table contains 2 calculation fields:
start_rate
rate_per_minute
A tables 'VoipDetails' and SessionDetails contains the folowing:
DATEDIFF(s, VoipDetails.SessionIdTime, SessionDetails.SessionEndTime)
If the correct prefix is found THEN use the following formule:
DATEDIFF(s, VoipDetails.SessionIdTime, SessionDetails.SessionEndTime))/60)*r.rate_per_minute)+start_rate)
Could you please give me an example for pl/sql ms sql server management studio?
If I understand your question correctly then you want a Scalar Function in T-SQL.
Check this out:
Create Function T-SQL Reference