COGNOiSe.com - The IBM Cognos Community

IBM Cognos 10 Platform => Cognos 10 BI => Framework Manager => Topic started by: ahmerzaidi on 28 Jun 2012 11:20:53 AM

Title: Error using T-SQL UDF Scalar Function
Post by: ahmerzaidi on 28 Jun 2012 11:20:53 AM
Hi All,

I've used the metadata wizard to import a UDF Scalar function from SQL Server 2008.  The function takes 4 parameters (int, string, string, date) and returns a float.

When trying to test the query I receive the following errors:

When running without Data Items from Query (using static parameters)

and

When running with Data Items from Query as parameters


Any suggestions?


Title: Re: Error using T-SQL UDF Scalar Function
Post by: ahmerzaidi on 28 Jun 2012 01:40:32 PM
Update:  The function works as expected when used in a stand alone query but does not work when used in a JOIN Query.

Any explanation as to why this is the case?
Title: Re: Error using T-SQL UDF Scalar Function
Post by: blom0344 on 29 Jun 2012 02:52:48 AM
Please post the definition of what you call 'join query' What error message do you get when testing the query subject? 
Title: Re: Error using T-SQL UDF Scalar Function
Post by: ahmerzaidi on 02 Jul 2012 04:01:47 PM
By 'JOIN Query' I am referring to the Query Subject output of a JOIN.  Errors are listed in the first post.
Title: Re: Error using T-SQL UDF Scalar Function
Post by: blom0344 on 03 Jul 2012 04:33:43 AM
If we can judge the SQL then we can perhaps make suggestions. In other words : The more you put into your posts , the better the chance you will get feedback
Title: Re: Error using T-SQL UDF Scalar Function
Post by: ahmerzaidi on 25 Jul 2012 07:55:36 AM
I believe I have isolated the issue further than I had when I created the original post.

The Native SQL generated within the report (below) seemed to be 2 separate query statements.

I failed to mentioned this earlier, as I did not think it was an issue until now, our model contains stored procedures which have relationship with tables.  When removing a data item that references query items from the stored procedure the generated Native SQL was a single statement.

Removing the data items referenced within the query items from the stored procedure had to be removed from the simple query and subsequently the join query.  Removing them only from the join query did not work.

The question now becomes how to get the functions to work with the use of query items from stored procedures used as parameters or data items within the JOIN query?

BEFORE
----Native SQL (Begin)----
select "Entity"."FundCurrency", "Entity"."FundID"
from "DB"."dbo"."Fund" "Entity"
where "Entity"."CustomerID" = xxxxxx
order by 2 asc
{call "DB"."dbo".cognos_fn_GetSecurityInformation(?,?)}

select "OpenPosition"."FK_CustomerID", "Security"."SecurityID", "Portfolios"."FundID", "Portfolios"."PortfolioName", "OpenPosition"."Quantity", "OpenPosition"."CostBasis", ("OpenPosition"."CostBasis" * "OpenPosition"."Quantity") * "Security"."SecurityMultiplier", "OpenPosition"."TaxBasis", ("OpenPosition"."TaxBasis" * "OpenPosition"."Quantity") * "Security"."SecurityMultiplier", "Security"."SecurityMultiplier", "OpenPosition"."BookValue", ("OpenPosition"."BookValue" * "OpenPosition"."Quantity") * "Security"."SecurityMultiplier", (("OpenPosition"."BookValue" - "OpenPosition"."TaxBasis") * "OpenPosition"."Quantity") * "Security"."SecurityMultiplier", "OpenPosition"."Currency", cast("OpenPosition"."Date" as date)
from "DB"."dbo"."OpenPosition" "OpenPosition", "DB"."dbo"."Security" "Security", "DB"."dbo"."Portfolios" "Portfolios"
where "OpenPosition"."FK_PortfolioID" = "Portfolios"."PortfolioID" and "OpenPosition"."FK_SecurityID" = "Security"."SecurityID" and "Portfolios"."CustomerID" = xxxxxx and "Security"."CustomerID" = xxxxxx and "OpenPosition"."FK_CustomerID" = xxxxxx
order by 2 asc
----Native SQL (End)----

AFTER (removing SP query items)
----Native SQL (Begin)----
select cast("coguda00"."Date" as date), "coguda00"."FK_CustomerID", "coguda02"."PortfolioName", "coguda01"."SecurityID", "Entity"."FundCurrency", "coguda00"."Currency", case "coguda00"."Currency" when 'USD' then 0 else 1 end , "DB"."dbo".fn_Get_ExchangeRate("coguda00"."FK_CustomerID", "coguda00"."Currency", "Entity"."FundCurrency", cast("coguda00"."Date" as date)), "coguda00"."Quantity", "coguda00"."CostBasis", ("coguda00"."CostBasis" * "coguda00"."Quantity") * "coguda01"."SecurityMultiplier", "coguda00"."TaxBasis", ("coguda00"."TaxBasis" * "coguda00"."Quantity") * "coguda01"."SecurityMultiplier", "coguda00"."BookValue", ("coguda00"."BookValue" * "coguda00"."Quantity") * "coguda01"."SecurityMultiplier", (("coguda00"."BookValue" - "coguda00"."TaxBasis") * "coguda00"."Quantity") * "coguda01"."SecurityMultiplier"
from "DB"."dbo"."OpenPosition" "coguda00", "DB"."dbo"."Security" "coguda01", "DB"."dbo"."Portfolios" "coguda02", "DB"."dbo"."Fund" "Entity"
where "coguda00"."FK_CustomerID" = xxxxxx and "coguda01"."CustomerID" = xxxxxx and "coguda02"."CustomerID" = xxxxxx and "coguda00"."FK_PortfolioID" = "coguda02"."PortfolioID" and "coguda00"."FK_SecurityID" = "coguda01"."SecurityID" and "Entity"."CustomerID" = xxxxxx and "coguda02"."FundID" = "Entity"."FundID"
----Native SQL (End)----
Title: Re: Error using T-SQL UDF Scalar Function
Post by: Rahul Ganguli on 01 Aug 2012 01:58:02 AM
In your DataSource set processing property to limited local.
Title: Re: Error using T-SQL UDF Scalar Function
Post by: blom0344 on 01 Aug 2012 04:16:05 AM
I wonder why you use stored procedures? If you want to pass parameters, then have a look what you can accomplish by using Cognos SQL queries with coded prompts. If your procedure is just a wrapper for some set based T-sql code, then you may be better off without them. I would only consider using stored procedures when no set based solution can be obtained and you need some procedural approach..
Title: Re: Error using T-SQL UDF Scalar Function
Post by: ahmerzaidi on 08 Aug 2012 11:32:02 AM
Rahul - Processing is set to Limited Local

Blom0344 - I'm using stored procedures because in our SQL Server Reporting Services environments we heavily use table functions to get information based on specific parameters. Seeing that Cognos does not handle table function they had to be wrapped in a store procedure.

I've had a PMR ticket open with IBM regarding this issue for a month now and the explanation I received so far is that this is a "system limitation" and they have never heard of this issue before.

It's hard to believe that I am the first person to use data items from a table and stored procedure (Query 1) and joining to another table (Query 2) and then preforming a SQL UDF function within the JOIN query.
Title: Re: Error using T-SQL UDF Scalar Function
Post by: Lynn on 08 Aug 2012 12:21:10 PM
I believe that Cognos is always going to generate SQL to just execute a stored procedure and bring back a result set, so joining it with anything else in the Cognos layer will result in the two result sets getting put together locally on the Cognos server and not via a database join. That is why you see two native SQL statements generated. That would eliminate the possibility of calling a SQL UDF in the joined query (as you've discovered).

Personally I suspect a poor data architecture if you need to use stored procedures in your reporting environment assuming it is intended to support reporting a la data warehousing principles, but that is another topic altogether.

In your situation you might consider creating a view that does the join between the SP and the table along with the UDF function and then model that in Framework Manager. Or maybe create a view that queries the SP and model the view instead of the proc. I would try an embedded prompt macro in the FM model as a way to satisfy the parameter passing. Not 100% sure I'm on the right track, but that's what I'd go for in your shoes.

The bottom line is that you have to force the join processing back on the database side instead of on the Cognos side if it is absolutely imperative that the UDF be executed based on the joined result set of the proc and the table.

Title: Error using T-SQL UDF Scalar Function
Post by: MFGF on 08 Aug 2012 01:51:49 PM
Wow! I just started reading this, and was going to suggest that your issue was local processing joining the SP result set and the SQL result set and building a projection list, preventing you calling a database function. Lynn pretty much said exactly what I was going to say! I would look at her suggestion of using a database view to join your SP with your table, utilising your db function, then model this view in FM.

Good luck!

MF.


Snet form my fumblefingers
iPhon 5 usig Tapatalk
Title: Re: Error using T-SQL UDF Scalar Function
Post by: ahmerzaidi on 09 Aug 2012 09:10:11 AM
Thanks everyone for your replies and suggestions.

As Lynn eluded to, the store procedures are in fact used to perform functionality that would normally be done within a data warehouse.  And as much as I agree that it is poor architecture, it is the only thing I have to work with. 

The reservations I have around wrapping a view around the store procedure is that all the stored procedures all take multiple parameters.  In order for the view to work I would need to strip the parameters and filter directly on the view.  This will cause an enormous performance degradation has some of the commonly used stored procedures would return 1M+ records without the parameters.
Title: Re: Error using T-SQL UDF Scalar Function
Post by: Lynn on 09 Aug 2012 09:16:15 AM
I was thinking the view could reference variables to pass to the SP and then a prompt macro in the FM model might work to satisfy those values, but you'd have to play with it to see. I'm really guessing on this so take it FWIW :)
Title: Re: Error using T-SQL UDF Scalar Function
Post by: ahmerzaidi on 09 Aug 2012 11:30:38 AM
I honestly don't even know how to start looking into this.  To my knowledge you cannot have parameters be passed in to a view that are passed to a stored procedure.  This is possible with a table functions but that bring us back to square one and the reason I have to use stored procedures in my FM model. 
Title: Re: Error using T-SQL UDF Scalar Function
Post by: Lynn on 09 Aug 2012 12:02:26 PM
I was thinking that something like Oracle's ability to prompt might exist in SQL Server and that the FM prompt macro might serve to satisfy that....long shot I suppose.

http://www.techonthenet.com/oracle/questions/parameter.php

So how about a SQL Server table UDF instead?

http://www.techrepublic.com/article/building-and-using-table-udfs-in-sql-server/6100403

Disclaimer: I'm not a DBA nor do I play one on TV.
Title: Re: Error using T-SQL UDF Scalar Function
Post by: ahmerzaidi on 09 Aug 2012 12:16:19 PM
I am not aware of the prompting function being available in SQL Server.  With regards to table UDF, this is how my issue started.  Cognos does not have support of table UDFs which is why I had to wrap them into a stored procedure.

One thing I tried was to take the table UDFs SQL code and used it as the Query Subject Definition using macro prompts in-line as filters.  The import was successful but the issue with running the UDF scalar function still failed in the same manner.
Title: Re: Error using T-SQL UDF Scalar Function
Post by: Lynn on 09 Aug 2012 12:26:56 PM
Sorry I'm out of ideas for you....apologies for all the red herrings :)

It would be worth posting if you find a solution as it is an interesting situation.
Title: Re: Error using T-SQL UDF Scalar Function
Post by: ahmerzaidi on 09 Aug 2012 12:39:11 PM
I'll definitely post the solution or whatever we decide our work around to be.  Thanks again!
Title: Error using T-SQL UDF Scalar Function
Post by: MFGF on 09 Aug 2012 09:32:29 PM
Quote from: ahmerzaidi on 09 Aug 2012 12:16:19 PM
I am not aware of the prompting function being available in SQL Server.  With regards to table UDF, this is how my issue started.  Cognos does not have support of table UDFs which is why I had to wrap them into a stored procedure.

One thing I tried was to take the table UDFs SQL code and used it as the Query Subject Definition using macro prompts in-line as filters.  The import was successful but the issue with running the UDF scalar function still failed in the same manner.

Did you try defining it as pass-thru SQL in the query subject? You can either do this in the options, or you can enclose the whole thing in two sets of braces {{Your code here}}

Just a straw to grasp at :)

MF.

Sent from my iPad using Tapatalk HD
Title: Re: Error using T-SQL UDF Scalar Function
Post by: ahmerzaidi on 10 Aug 2012 06:15:51 AM
Just tried both suggestions and unfortunately no luck.
Title: Re: Error using T-SQL UDF Scalar Function
Post by: CognosPaul on 12 Aug 2012 04:03:11 PM
I don't have any experience with table functions, unfortunately. Have you tried writing the query by hand in the framework query? Forget the import wizard, try with the curly brackets:

{select myFunction(#prompt('whatever','integer')#)}
Title: Re: Error using T-SQL UDF Scalar Function
Post by: ahmerzaidi on 13 Aug 2012 10:46:42 AM
Quote from: PaulM on 12 Aug 2012 04:03:11 PM
I don't have any experience with table functions, unfortunately. Have you tried writing the query by hand in the framework query? Forget the import wizard, try with the curly brackets:

{select myFunction(#prompt('whatever','integer')#)}

I did attempted this approach, it seems like Cognos it the same way as the store procedure.