passing parameters to VO SQL transient attribute - oracle-adf

I created a view object for scott.emp table
I added a transient attribute, then change the default value to be from SQL and wrote statement like this:
select max(nvl(sal, 0)) from emp where deptno = view.deptno
my problem is: how to pass view.deptno as parameter to sql statement ?
running the page ,I have got an error.
ORA-00904: "EMP_VO"."DEPTNO": invalid identifier

I solved this by inspiration from previous answer, as I wrote in sql field in Default values the following clause by using Entity attribute so it works.
select max(nvl(sal, 0)) from emp where deptno = Emp_EO.DEPTNO
In my first post I used View object attribute in where clause, but this throws above error ORA-00904.
the condition values in where clause must be entity attribute not view attribute.
Emp_EO.DEPTNO

If you check your VO's query, it should looks similar to this:
SELECT Emp.EMPNO,
Emp.ENAME,
Emp.JOB,
Emp.MGR,
Emp.HIREDATE,
Emp.SAL,
Emp.COMM,
Emp.DEPTNO,
(select max(nvl(sal, 0)) from emp where deptno = Emp.DEPTNO)
FROM EMP Emp

Related

How to add a dynamic parameter in Mule4 Select Query

I have a SELECT query for which the entire WHERE condition is coming from a Java class. How can I use the entire WHERE condition in the SELECT query? This is what I tried:
SELECT * FROM EMPLOYEE_TABLE WHERE 1=1 #[payload]
Here payload is a WHERE clause coming from a Java class: NAME = VKP AND STATE = PA AND CITY = KOP
I am getting an error message like " parameter null was not bound for query select…", but I am able to see the payload value coming out from the Java class and in the logs.
You should not use an expression directly in the query. Instead assign the query in an expression to a variable, then use the variable as the query.
For example something like:
<set-variable value="#['SELECT * FROM EMPLOYEE_TABLE WHERE 1=1 ' ++ payload]" name="query" />
<db:select ...>
<db:sql>#[vars.query]</db:sql>
</db:select>
Note that you risk having SQL injections vulnerabilities doing this.

Error: an expression of non-boolean type specified in a context where a condition is expected, near ',' ; Using Cascading Parameters

I am trying to use cascading parameters to filter this Pivot table in SSRS Report Builder.
This is the main dataset query:
SELECT * FROM(
SELECT *,
CASE WHEN PLN=PLN THEN '01. GROSS PREMIUM'
ELSE NULL
END AS PREMIUM
FROM MYI
PIVOT (SUM(GROSS_PREMIUM_1) FOR PERIOD_TYPE IN([MTD],[YTD],[ITD])) pvt
UNION ALL
SELECT *,
CASE WHEN PLN=PLN THEN '02. REFUND'
ELSE NULL
END AS PREMIUM
FROM MYI
PIVOT (SUM(REFUND_2) FOR PERIOD_TYPE IN([MTD],[YTD],[ITD])) pvt
)A
WHERE ACC_PERIOD = #ACC_PERIOD
AND REINSURER IN (#REINSURER)
AND INSURER IN (#INSURER)
AND PLN IN (#PLN)
AND SVC_AGY IN (#SVC_AGY)
These parameters in the WHERE clause each have their own dataset and are cascaded from top to bottom.
Here is the query for the final parameter as an example:
SELECT DISTINCT [fasren_servicingagency]
FROM [FAS_ReinsuranceNumber]
WHERE ACC_PERIOD = #ACC_PERIOD
AND REINSURER IN (#REINSURER)
AND INSURER IN (#INSURER)
AND PLN IN (#PLN)
ORDER BY SVC_AGY
The query runs fine in SSMS, but I keep getting this error when I run it in the SSRS report builder:
An expression of non-boolean type specified in a context where a condition is expected, near ','
It must have something to do with the WHERE clause in either the main query or the parameter dataset queries. I have seen many posts about this error but I could not find a solution that helped with my problem. Any ideas?
NOTE: all parameters are character fields, no integers, no date columns.
EDIT: There is another query that I was successful with;
SELECT [acctyymm],
[retrosummary],
[retroagent],
[coveragedivision],
[policyinsurer],
SUM([NetDue]) AS NET_DUE,
SUM([ActualPayable]) AS PAYABLE
FROM [dbo].[RetroNumberGAAP]
WHERE [acctyymm] IN (#ACC_PERIOD)
AND [retrosummary] IN (#RETSUM)
AND [retroagent] IN (#RETAGT)
AND [coveragedivision] IN (#PLN)
AND [policyinsurer] IN (#INSURER)
AND POWER([fasrtng_NetDue],2)+POWER([ActualPayable],2)<>0
GROUP BY [acctyymm],
[retrosummary],
[retroagent],
[coveragedivision],
[policyinsurer]
How am I successful running the report with cascaded parameters in this second query and not the first query?
I figured out what I did wrong. My Dataset properties were not configured correctly in the Report Builder.
WRONG CONFIGURATION
Dataset properties; Parameters; parameter name: SVC_AGY Parameter Value: [#SVC_AGY]
CORRECTED CONFIGURATION
Dataset properties; Parameters; parameter name: #SVC_AGY Parameter Value: [#SVC_AGY]
Make sure your parameter names match your parameter values, including the # symbol.

Why do I get "Synonym 'syn.Syn_AAA' refers to an invalid object" Error?

When I execute a stroed procedure it works. But specifically when I run the select statement I get the following error
Synonym 'syn.Syn_NEO_DB_tGradeAliases' refers to an invalid object.
SELECT
aa.CompanyId [LegCompanyId],
aa.ProductId AS [LegGradeId],
aa.GradeAliasId [LegGradeAliasId],
aa.ProductName AS [LobGradeText],
aa.[Alias] [GradeAlias],
aa.PhraseKey [PhraseKey],
GETUTCDATE() AS 'TimeStamp'
FROM syn.Syn_AAA aa
I haven't done any database change/permission change.
How can I overcome this?
I ran following query and it shows the base_object_name correctly linked to my table.
SELECT * FROM sys.synonyms WHERE name = 'Syn_AAA'
I overcame by replacing synonym with [LINKED_SERVER].[DB_NAME].[SCHEMA_NAME].[OBJECT_NAME].

Update SQL Server table using XML data

From my ASP.Net application I am generating XML and pass it as input data to stored procedure as below,
<Aprroval>
<Approve>
<is_nb_approved>false</is_nb_approved>
<is_approved>true</is_approved>
<is_submitted>true</is_submitted>
<UserId>35</UserId>
<ClientId>405</ClientId>
<taskDate>2015-05-23T00:00:00</taskDate>
</Approve>
<Approve>
<is_nb_approved>false</is_nb_approved>
<is_approved>true</is_approved>
<is_submitted>true</is_submitted>
<UserId>35</UserId>
<ClientId>405</ClientId>
<taskDate>2015-05-24T00:00:00</taskDate>
</Approve>
</Approval>
And below is my stored procedure,
create procedure UpdateTaskStatus(#XMLdata XML)
AS
UPDATE [TT_TaskDetail]
SET
is_approved=Row.t.value('(is_approved/text())[1]','bit'),
is_nb_approved=Row.t.value('(is_nb_approved/text())[1]','bit'),
is_submitted=Row.t.value('(is_submitted/text())[1]','bit')
FROM #XMLdata.nodes('/Aprroval/Aprrove') as Row(t)
WHERE user_id = Row.t.value('(UserId/text())[1]','int')
AND client_id = Row.t.value('(ClientId/text())[1]','int')
AND taskdate = Row.t.value('(taskDate/text())[1]','date')
But when I execute this stored procedure, I am getting return value as 0 and no record is getting updated. Any suggestions welcome.
You have 2 errors in your xml:
First is nonmatching root tags.
Second, more important, you are quering nodes('/Aprroval/Aprrove'), but inner tag is Approve not Aprrove.
Fiddle http://sqlfiddle.com/#!3/66b08/3
Your outer tags do not match. Your opening tag says, "Aprroval" instead of "Approval". Once I corrected that, I was able to select from the XML without issue.

How do I update an XML column in sql server by checking for the value of two nodes including one which needs to do a contains (like) comparison

I have an xml column called OrderXML in an Orders table...
there is an XML XPath like this in the table...
/Order/InternalInformation/InternalOrderBreakout/InternalOrderHeader/InternalOrderDetails/InternalOrderDetail
There InternalOrderDetails contains many InternalOrderDetail nodes like this...
<InternalOrderDetails>
<InternalOrderDetail>
<Item_Number>FBL11REFBK</Item_Number>
<CountOfNumber>10</CountOfNumber>
<PriceLevel>FREE</PriceLevel>
</InternalOrderDetail>
<InternalOrderDetail>
<Item_Number>FCL13COTRGUID</Item_Number>
<CountOfNumber>2</CountOfNumber>
<PriceLevel>NONFREE</PriceLevel>
</InternalOrderDetail>
</InternalOrderDetails>
My end goal is to modify the XML in the OrderXML column IF the Item_Number of the node contains COTRGUID (like '%COTRGUID') AND the PriceLevel=NONFREE. If that condition is met I want to change the PriceLevel column to equal FREE.
I am having trouble with both creating the xpath expression that finds the correct nodes (using OrderXML.value or OrderXML.exist functions) and updating the XML using the OrderXML.modify function).
I have tried the following for the where clause:
WHERE OrderXML.value('(/Order/InternalInformation/InternalOrderBreakout/InternalOrderHeader/InternalOrderDetails/InternalOrderDetail/Item_Number/node())[1]','nvarchar(64)') like '%13COTRGUID'
That does work, but it seems to me that I need to ALSO include my second condition (PriceLevel=NONFREE) in the same where clause and I cannot figure out how to do it. Perhaps I can put in an AND for the second condition like this...
AND OrderXML.value('(/Order/InternalInformation/InternalOrderBreakout/InternalOrderHeader/InternalOrderDetails/InternalOrderDetail/PriceLevel/node())[1]','nvarchar(64)') = 'NONFREE'
but I am afraid it will end up operating like an OR since it is an XML query.
Once I get the WHERE clause right I will update the column using a SET like this:
UPDATE Orders SET orderXml.modify('replace value of (/Order/InternalInformation/InternalOrderBreakout/InternalOrderHeader/InternalOrderDetails/InternalOrderDetail/PriceLevel[1]/text())[1] with "NONFREE"')
However, I ran this statement on some test data and none of the XML columns where updated (even though it said zz rows effected).
I have been at this for several hours to no avail. Help is appreciated. Thanks.
if you don't have more than one node with your condition in each row of Orders table, you can use this:
update orders set
data.modify('
replace value of
(
/Order/InternalInformation/InternalOrderBreakout/
InternalOrderHeader/InternalOrderDetails/
InternalOrderDetail[
Item_Number[contains(., "COTRGUID")] and
PriceLevel="NONFREE"
]/PriceLevel/text()
)[1]
with "FREE"
');
sql fiddle demo
If you could have more than one node in one row, there're a several possible solutions, none of each is really elegant, sadly.
You can reconstruct all xmls in table - sql fiddle demo
or you can do your updates in the loop - sql fiddle demo
This may get you off the hump.
Replace #HolderTable with the name of your table.
SELECT T2.myAlias.query('./../PriceLevel[1]').value('.' , 'varchar(64)') as MyXmlFragmentValue
FROM #HolderTable
CROSS APPLY OrderXML.nodes('/InternalOrderDetails/InternalOrderDetail/Item_Number') as T2(myAlias)
SELECT T2.myAlias.query('.') as MyXmlFragment
FROM #HolderTable
CROSS APPLY OrderXML.nodes('/InternalOrderDetails/InternalOrderDetail/Item_Number') as T2(myAlias)
EDIT:
UPDATE
#HolderTable
SET
OrderXML.modify('replace value of (/InternalOrderDetails/InternalOrderDetail/PriceLevel/text())[1] with "MyNewValue"')
WHERE
OrderXML.value('(/InternalOrderDetails/InternalOrderDetail/PriceLevel)[1]', 'varchar(64)') = 'FREE'
print ##ROWCOUNT
Your issue is the [1] in the above.
Why did I put it there?
Here is a sentence from the URL listed below.
Note that the target being updated must be, at most, one node that is explicitly specified in the path expression by adding a "[1]" at the end of the expression.
http://msdn.microsoft.com/en-us/library/ms190675.aspx
EDIT.
I think I've discovered the the root of your frustration. (No fix, just the problem).
Note below, the second query works.
So I think the [1] is some cases is saying "only ~~search~~ the first node".....and not (as you and I were hoping)...... "use the first node..after you find a match".
UPDATE
#HolderTable
SET
OrderXML.modify('replace value of (/InternalOrderDetails/InternalOrderDetail/PriceLevel/text())[1] with "MyNewValue001"')
WHERE
OrderXML.value('(/InternalOrderDetails/InternalOrderDetail/PriceLevel[text() = "NONFREE"])[1]', 'varchar(64)') = 'NONFREE'
/* and OrderXML.value('(/InternalOrderDetails/InternalOrderDetail/Item_Number)[1]', 'varchar(64)') like '%COTRGUID' */
UPDATE
#HolderTable
SET
OrderXML.modify('replace value of (/InternalOrderDetails/InternalOrderDetail/PriceLevel/text())[1] with "MyNewValue002"')
WHERE
OrderXML.value('(/InternalOrderDetails/InternalOrderDetail/PriceLevel[text() = "FREE"])[1]', 'varchar(64)') = 'FREE'
Try this :
;with InternalOrderDetail as (SELECT id,
Tbl.Col.value('Item_Number[1]', 'varchar(40)') Item_Number,
Tbl.Col.value('CountOfNumber[1]', 'int') CountOfNumber,
case
when Tbl.Col.value('Item_Number[1]', 'varchar(40)') like '%COTRGUID'
and Tbl.Col.value('PriceLevel[1]', 'varchar(40)')='NONFREE'
then 'FREE'
else
Tbl.Col.value('PriceLevel[1]', 'varchar(40)')
end
PriceLevel
FROM (select id ,orderxml from demo)
as a cross apply orderxml.nodes('//InternalOrderDetail')
as
tbl(col) ) ,
cte_data as(SELECT
ID,
'<InternalOrderDetails>'+(SELECT ITEM_NUMBER,COUNTOFNUMBER,PRICELEVEL
FROM InternalOrderDetail
where ID=Results.ID
FOR XML AUTO, ELEMENTS)+'</InternalOrderDetails>' as XML_data
FROM InternalOrderDetail Results
GROUP BY ID)
update demo set orderxml=cast(xml_data as xml)
from demo
inner join cte_data on demo.id=cte_data.id
where cast(orderxml as varchar(2000))!=xml_data;
select * from demo;
SQL Fiddle
I have handled following cases :
1. As required both where clause in question.
2. It will update all <Item_Number> like '%COTRGUID' and <PriceLevel>= NONFREE in one
node, not just the first one.
It may require minor changes for your data and tables.

Resources