Executing a stored procedure with OUTPUT parameters - Jimmy Rishe
in

InfoPath Dev

Jimmy Rishe

Executing a stored procedure with OUTPUT parameters

Many people are aware that you can use InfoPath code or script to perform all sorts of database queries on tables, views, stored procedures and the like.  I won't go into the details here, but you can read more about this at the following links:

http://www.infopathdev.com/forums/p/9467/33496.aspx#33496
http://www.infopathdev.com/forums/p/8940/31780.aspx#31780

 But what happens when you want to query a stored procedure that uses OUTPUT parameters?  I ran into this issue while helping a forum poster in this thread:

http://www.infopathdev.com/forums/t/12506.aspx

 Suppose I have this elementary stored procedure, which returns the square and half of the input value:

CREATE PROCEDURE [dbo].[SimpleStoredProcedure]
     @inputValue
int, 
    
@inputSquared bigint output,
    
@inputHalved int output
AS
BEGIN

     SET
NOCOUNT ON;
    
SET @inputSquared = CAST(@inputValue as bigint) * CAST(@inputValue AS bigint)
    
SET @inputHalved = @inputValue / 2

    
-- return some value just for the heck of it
    
return 7
END

If I try to execute this procedure from InfoPath code like this (C# 2007 here):

AdoQueryConnection conn = DataConnections["TestDatabase"] as AdoQueryConnection;
string originalCommand = conn.Command;
string query = "EXECUTE SimpleStoredProcedure 23";  // just pass in 23 as an arbitrary value
conn.Command = query;
conn.Execute();
conn.Command = originalCommand;
RunQuery(query);
 

I get this error:

The query cannot be run for the following DataObject: TestDatabase
InfoPath cannot run the specified query.
[0x80040E10][Microsoft OLE DB Provider for SQL Server] Procedure or function 'SimpleStoredProcedure' expects parameter '@inputSquared', which was not supplied.

this is because my query does not give the stored procedure any place to store the values of its output parameters.  What's more, I have no way of accessing these parameters because by default, InfoPath only receives the value of the return statement from a stored procedure, which would always be 7 in this case.

The solution:

The thing to remember here is that you don't have to limit yourself to having just one SQL statement in your query.  You can have several.  And that's just what we need here.

What we can do is have the query create some SQL variables to hold the output parameters, and then SELECT them so that their values get sent back to InfoPath.  First we create the SQL variables and pass them into the stored procedure:

DECLARE @squareOutput bigint, @halfOutput int
EXECUTE
SimpleStoredProcedure 23, @squareOutput OUTPUT, @halfOutput OUTPUT

We can do this by modifying the third line of my code above to:

 string query = "DECLARE @squareOutput bigint, @halfOutput int " +
    "EXECUTE SimpleStoredProcedure 23, @squareOutput OUTPUT, @halfOutput OUTPUT"
;
[GOTCHA: Don't forget the space at the end of the first line of the statement or you will wind up with something like intEXECUTE in your statement]

This is still incomplete because no values come back from the query, and the secondary data source's contents look like this:

<dfs:myFields xmlns:dfs="http://schemas.microsoft.com/office/infopath/2003/dataFormSolution"/>

To finish this solution off, we need to SELECT the value of the SQL variables so that they will be sent back to InfoPath, like this:

SELECT @squareOutput AS SquareOut, @halfOutput AS HalfOut

I've specified aliases (SquareOut and HalfOut) for the SELECT column names because otherwise they will come back without names and InfoPath will give them meaningless names like c0 and c1.

The code looks like this at this point:

 string query = "DECLARE @squareOutput bigint, @halfOutput int " +
    "EXECUTE SimpleStoredProcedure 23, @squareOutput OUTPUT, @halfOutput OUTPUT " +
    "SELECT @squareOutput AS SquareOut, @halfOutput AS HalfOut"
;
[Again, don't forget the space at the end of the second line of the statement]

Finally, we run the query, and we get back our result, with our requested values:

<dfs:myFields xmlns:dfs="http://schemas.microsoft.com/office/infopath/2003/dataFormSolution">
     <dfs:dataFields>
          <d:row xmlns:d="http://schemas.microsoft.com/office/infopath/2003/ado/dataFields" HalfOut="529" SquareOut="11"/>
     </dfs:dataFields>
</dfs:myFields>

Comments

 

sasyregak said:

Jimmy

Thanks for your tips... I was stuggling to get this achieved.

/ Get the default SQL command for the form.

var strOrigSQLCommand = XDocument.QueryAdapter.Command;

//Find the value of the filter criteria

var strInspectionValuationhistory = XDocument.DOM.selectSingleNode("/dfs:myFields/dfs:queryFields/q:Inspection_Valuation_history");

var strvisit = strInspectionValuationhistory.selectSingleNode("@Which_visit").text;

strvisit = strvisit - 1; //store the previous visit value

if(strvisit != "")

{

strpreviousvisitSQLcommand = "DECLARE @Previousvisitdate datetime " + " EXECUTE test " + strvisit + " ,@Previousvisitdate OUTPUT " + " SELECT @Previousvisitdate as previousdate";

}

XDocument.UI.Alert(strpreviousvisitSQLcommand);

XDocument.QueryAdapter.Command = strpreviousvisitSQLcommand;

XDocument.Query();

//Here i need to get the result stored in a global variable , so that i can refer in any other view whereever required.......please guide me

XDocument.QueryAdapter.Command = strOrigSQLCommand;

XDocument.Query();

August 27, 2009 5:46 AM
 

sasyregak said:

Further after trouble shooting....I am able to find the output of the query in query analyser giving rise to a date value(single).

But the preview on infopath given the following error

The query cannot be run for the following DataObject: Report connection

The XML data returned from the data source does not match the XML Schema for this form. This discrepancy might be caused by the data source returning multiple rows when InfoPath expects only one.

Element '{schemas.microsoft.com/.../dataFields}row' is unexpected according to content model of parent element '{schemas.microsoft.com/.../dataFormSolution}dataFields'.

Expecting: {schemas.microsoft.com/.../dataFields}FileGeneralInfo.

Appreciate your help on this.....

August 28, 2009 6:02 AM
 

uberVU - social comments said:

This post was mentioned on Twitter by InfoPathDev: Blog: Executing a stored procedure with OUTPUT parameters in InfoPath - http://su.pr/7WfE2W

October 30, 2009 9:56 AM
 

Jimmy said:

Hey sasyregak,

Sorry for not responding to your post until now.  I don't get notifications about comments on my blog posts and the easiest way to get a response is to open a new forum post.

It sounds like you are trying to use this technique on your main data source.  InfoPath performs schema validation on the main data source and an operation like this that returns a schema other than the expected one will cause that error.

Might you be able to try this technique on a secondary data source?

November 29, 2009 9:32 PM
Copyright © 2003-2019 Qdabra Software. All rights reserved.
View our Terms of Use.