views:

52

answers:

3

Using SQL Server 2005, I'd like to run a stored procedure and insert all of the results into a new table.

I'd like the new table to have its columns automatically configured based upon the data returned by the stored procedure.

I am familiar with using the SELECT ... INTO syntax:

SELECT * INTO newtable FROM oldtable

Is this possible?

Edit for clarification: I'm hoping to accomplish something like:

Select * INTO newtable FROM exec My_SP
A: 

A variation of the same is

create table somename
  select * from wherever;
wallyk
+2  A: 

The only way to do this is w/ OPENROWSET against the local server:

SELECT * INTO #temp 
FROM OPENROWSET (
    'SQLOLEDB'
  , 'Server=(local);TRUSTED_CONNECTION=YES;'
  , 'SET FMTONLY OFF EXEC database.schema.procname'
  ) a

But this is kind of a last-ditch-gotta-do-it-damn-the-consequences kind of method. It requires elevated permissions, won't work for all procedures, and is generally inefficient.

More info and some alternatives here: http://www.sommarskog.se/share_data.html

Peter
Sorry @Peter, I mentioned Erland's link in a follow-up comment to my answer; didn't realize you had already pointed it out.
Aaron Bertrand
+2  A: 

This seems like a horrible design. You're really going to create a new table to store the results of a stored procedure, every time the stored procedure is called? And you really can't create the table in advance because you have absolutely no idea what kind of output the stored procedure has? What if the stored procedure returns multiple resultsets? What if it has side effects?

Okay, well, if that's what you really want to do...

One way to accomplish this is to use your local server as a linked server and utilize OPENQUERY. First you need to make sure your local server is configured for data access:

EXEC sp_serveroption 'local server name', 'DATA ACCESS', true;

Then you can do something like this:

SELECT * INTO dbo.newtable
FROM OPENQUERY('local server name', 'EXEC yourdb.dbo.yourproc;');

PS How are you going to write code that is going to perform SELECT INTO into a new table name every time (because you can only do SELECT INTO once)? Dynamic SQL? What happens if two users run this code at the same time? Does one of them win, and the other one just gets an error message?

Aaron Bertrand
What do you think, is OPENQUERY or OPENROWSET best for this kind of thing? I haven't enough experience or testing to know if it makes a difference, or in what dimensions.
Peter
hamlin11
@Peter, my gut tells me that using OPENQUERY is a bit faster, since it uses the native provider and the linked server directly, vs. going out to the operating system to use the OLEDB provider... I imagine there's got to be some overhead with that. But I'll qualify my statement to say that I have not done any extensive performance testing. In this case given the OP's additional comments it does not seem like a performance sensitive thing so I guess it is not much of a decision factor.
Aaron Bertrand
@hamlin11, a couple of links I'll point you to. One is Erland's article on sharing data between procedures, there might be some other tidbits in there that can help: http://www.sommarskog.se/share_data.html and I agree that access to stored procedure metadata is weak (it would be nice if you could do like with tables - in Object Explorer, expand a table, and drag the columns node onto a query window - magic!). Maybe this is a good idea for you (Greg Low is asking for an SP "contract" where metadata is better exposed): http://bit.ly/94aQ1H / http://bit.ly/92c1HI
Aaron Bertrand
That comment on Microsoft Connect by rajmundr re: XML+XSD was interesting. Something to consider.
Peter