Re: Determining column names and types of recordset returned by stored procedure
From: Dave Hall (dhall_at_nospam.deboy.com)
Date: 01/26/05
- Next message: Aleks: "SQL Expert"
- Previous message: Andrew J. Kelly: "Re: controlling temdb size"
- In reply to: Aaron Weiker: "Re: Determining column names and types of recordset returned by stored procedure"
- Messages sorted by: [ date ] [ thread ]
Date: Tue, 25 Jan 2005 22:02:10 -0500
Thanks Louis & Aaron.
Your suggestions about using profiler got me on track. It seems that VS
Server Explorer calls sp_procedure_params_rowset to get the parameters of
the proc then builds a command to be executed including dummy parameters
then wraps the call to the proc with SET NO_BROWSETABLE and SET FMTONLY
statements. Since the values don't matter, I use null in my version below
rather than worrying about data types of the dummy values.
The follwoing 5 lines are a stripped down version of the call to the proc as
shown in profiler.
SET NO_BROWSETABLE ON
SET FMTONLY ON
EXEC MyProc null , null -- add proper number of placeholder parameters here.
in this case, there are 2.
SET FMTONLY OFF
SET NO_BROWSETABLE OFF
An interesting note - In some procs which potentially return a variety of
schemas, the code above actually returns one empty recordset for each
possible code path, but all recordsets are empty. Visual Studio only
displays the first recrdset's schema in this case, but all are available.
For example, consider this proc which can return one of two recordsets with
each possible recordset having a different schema depending on the @mode
parameter:
---- create procedure dbo.VariousTables ( @mode integer ) as set nocount on if @mode is null select 'Mode is null' as TextResults else select @mode as IntegerResults, newid() as GuidResults go SET NO_BROWSETABLE ON SET FMTONLY ON EXEC VariousTables null SET FMTONLY OFF SET NO_BROWSETABLE OFF go drop procedure VariousTables ----- In this case, the results include both tables, but no data in either table as follows: TextResults ------------ IntegerResults GuidResults -------------- ------------------------------------ In this case, Visual Studio would only show TextResults as a resulting column since it occurs first. One last thing, if one proc calls another, this method still returns all possible results of every code path including the nested proc. Pretty cool! It looks like my original idea of calling the proc within a transaction and roling it back wasn't too far off, but this provides a much better solution besides the fact that I can now easily see any possible resulting schema. It's better than I had hoped for. Thanks again all. Dave "Aaron Weiker" <aaron@sqlprogrammer.org> wrote in message news:137122632422726493538307@news.microsoft.com... > Hello Dave, > I think what it's doing is actually taking a look at the stored procedure > and then tries to find out what values are being returned based upon the > select statements. > > So the easiest thing to do would just be to open up VS and profiler and see > what is sent to the database. > > Someone where I work also mentioned that CodeSmith has a similar functionality > that you are looking for so you may want to try looking there for some additional > insight. > > -- > Aaron Weiker > http://aaronweiker.com/ > > > Thanks Aaron, > > I understand the problem you mention, and I understand that the > > results > > from any attempt to determine such info is not guaranteed accurate > > since, as > > you put it, "there's no contract". Nonetheless, I see that the Visual > > Studio 2003 Server explorer is reliably providing the information > > about storedprocedures that I'm trying to retreive, so I wonder how > > it's getting that information, even if it's just an educated guess > > rather than a contract. > > > > Dave > > > > "Aaron Weiker" <aaron@sqlprogrammer.org> wrote in message > > news:135990632422698471294730@news.microsoft.com... > > > >> Hello Dave, > >> There is no such contract to define what a stored procedure will > >> return. > >> The same procedure can return 100 columns, just 5, or nothing at all. > >> -- > >> Aaron Weiker > >> http://aaronweiker.com/ > >>> How can I determine the columns that will normally be returned from > >>> a particular stored proc without actually executing it? > >>> > >>> I understand that a proc may return no recordset, one recordset, or > >>> multiple recordsets, but assuming that none of my procs return more > >>> than one recordset, is there a way I can determine the structure of > >>> that proc's resulting recordset without actually running it? For > >>> example, I can query sysobjects and syscolumns (or use any of > >>> several built in procs) to get such info about a table as follows. > >>> > >>> select sysobjects.Name as [TableName], > >>> syscolumns.Name as [ColumnName], > >>> systypes.Name as [TypeName], > >>> COLUMNPROPERTY ( object_id(sysobjects.name) , syscolumns.name , > >>> 'Precision' ) as [Precision], > >>> COLUMNPROPERTY ( object_id(sysobjects.name) , syscolumns.name , > >>> 'Scale' ) > >>> as [Scale] > >>> from sysobjects (nolock) > >>> join syscolumns syscolumns (nolock) > >>> on syscolumns.id = sysobjects.id > >>> join systypes systypes (nolock) > >>> on systypes.xtype = syscolumns.xtype > >>> and systypes.xusertype = syscolumns.xusertype > >>> where sysobjects.Type = 'u' > >>> I'm looking for something roughly analagous to the query above, > >>> except > >>> changing the where clause to > >>> where sysobjects.Type = 'p' > >>> > >>> When I do this, it returns the parameters of the procs, but not any > >>> info about their resulting recordsets (if any). > >>> > >>> As I said, I undersand why such a query would be problematic given > >>> that a proc could return any number of different recordsets each > >>> having different schemas depending on different criteria in the > >>> database or parameters of the proc. Even so. I see that the Visual > >>> Studio Server Explorer displays the exact info that I'm trying to > >>> retrieve, but it hopefully doesn't execute any of the procs in order > >>> to glean this info. > >>> > >>> Any suggestions on how Visual Studio Servrer Explorer does it or how > >>> I might accomplish it? I thought about calling the procs within a > >>> transaction and passing all null parameters, then rolling back the > >>> transaction after I evaluate the recordset, but this seems way too > >>> complicated and could potentially affect the database if triggers > >>> were fired or identity fields incremented that the transaction > >>> didn't roll back. > >>> > >>> I know it's do-able since VS 2003 is doing it, even if I have to > >>> make certain assumsions about the procs such as the assumsion that > >>> they don't return multiple recordsets. Can anyone help me get > >>> started in the right direction? > >>> > >>> Thanks in advance. > >>> Dave > >
- Next message: Aleks: "SQL Expert"
- Previous message: Andrew J. Kelly: "Re: controlling temdb size"
- In reply to: Aaron Weiker: "Re: Determining column names and types of recordset returned by stored procedure"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|