| Author |
Topic |
|
ed_ward_graham
Starting Member
15 Posts |
Posted - 2008-12-06 : 07:30:31
|
| I need to execute an arbitrary SELECT statement (inside an EXEC command) and store the results in a temporary table. I don't know how many columns the SELECT statement will contain.If I had the SELECT statement explicitly, I could do this:SELECT 'a' AS a, 'b' AS b, 'c' AS c, ...INTO #tempTableOn the other hand, if I knew the number of columns (and their types), I could do this:DECLARE @selectStatement VARCHAR(MAX)SET @selectStatement = 'SELECT ''a'', ''b'', ''c'''DECLARE @tempTable TABLE( a varchar(max), b varchar(max), c varchar(max))INSERTINTO @tempTableEXEC (@selectStatement)SELECT * FROM @tempTableWhat I need is something that does both! I triedDECLARE @selectStatement VARCHAR(MAX)SET @selectStatement = 'SELECT ''a'', ''b'', ''c'''EXEC (@selectStatement)INTO #tempTablebut it doesn't work.All answers gratefully received! |
|
|
sodeep
Master Smack Fu Yak Hacker
7174 Posts |
Posted - 2008-12-06 : 08:38:36
|
| See this:http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=70626 |
 |
|
|
ed_ward_graham
Starting Member
15 Posts |
Posted - 2008-12-07 : 19:06:03
|
| Ah -- it seems that UDFs are my answer, not stored procedures. Thanks very much, Sodeep. |
 |
|
|
ed_ward_graham
Starting Member
15 Posts |
Posted - 2008-12-09 : 10:29:38
|
| Actually, they weren't -- I understand that you cannot execute dynamic SQL in a UDF, is this right? I am now looking at OPENQUERY instead but it doesn't seem to be ideal either, so my question is still open! |
 |
|
|
sodeep
Master Smack Fu Yak Hacker
7174 Posts |
Posted - 2008-12-09 : 10:32:30
|
| Where did you see UDF in that link? Use Mladen Openquery. |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-12-09 : 11:00:50
|
quote: Originally posted by ed_ward_graham Actually, they weren't -- I understand that you cannot execute dynamic SQL in a UDF, is this right? I am now looking at OPENQUERY instead but it doesn't seem to be ideal either, so my question is still open!
why does your resultset vary dynamically? |
 |
|
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2008-12-09 : 11:39:02
|
Correct - No dynamic SQL in a udf.You should examine why you want to do this. I can't see a good reason. Is this some sort of report?You *can* do stuff like this to get a table out at the end. It's not pretty and, well, it's not a good idea at all really.IF OBJECT_ID('CS_ColumnTest') IS NOT NULL DROP PROCEDURE CS_ColumnTestGOCREATE PROCEDURE CS_ColumnTest AS BEGINDECLARE @sql NVARCHAR(4000)ALTER TABLE #t ADD [col2] VARCHAR(255)SET @sql = 'UPDATE #t SET [col2] = LEFT([col1], 1)'EXEC sp_executeSql @sqlENDGOIF OBJECT_ID('tempDb..#t') IS NOT NULL DROP TABLE #tCREATE TABLE #t ( [col1] VARCHAR(50) )INSERT #t SELECT 'A'UNION SELECT 'Really'UNION SELECT 'Bad'UNION SELECT 'Idea'SELECT * FROM #tEXEC dbo.CS_ColumnTestSELECT * FROM #tGOIF OBJECT_ID('CS_ColumnTest') IS NOT NULL DROP PROCEDURE CS_ColumnTestIF OBJECT_ID('tempDb..#t') IS NOT NULL DROP TABLE #tCharlie===============================================================Msg 3903, Level 16, State 1, Line 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
 |
|
|
ed_ward_graham
Starting Member
15 Posts |
Posted - 2008-12-09 : 11:41:36
|
| Thanks a lot for the replies. I basically have tables in a database that contain SELECT statements, and ASP.NET code that reads these statements and then executes them. A sort of "recursive database" if you see what I mean (for want of much better phrasing). In a stored procedure, I now need to pick out these select statements and execute them, then process the resulting tables. |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-12-09 : 11:43:42
|
quote: Originally posted by ed_ward_graham It seems that there is no way to do this. Can anyone verify this fact for me?To recap: I am trying to execute an arbitrary SQL statement and store the results in a table (temporary, permanent, variable -- I don't mind). It doesn't appear to be possible to do this in SQL 2005, which is astonishing.
you still didnt explain why resultset vary dynamically? why is it arbitrary? |
 |
|
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2008-12-09 : 11:46:58
|
| I posted 1 way you *could* do it.I also said that you shouldn't.Kindly do as Viskah16 suggests and explain what you want (specifically - not generally) otherwise we are neither going to have the inclination or ability to help you.Charlie===============================================================Msg 3903, Level 16, State 1, Line 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
 |
|
|
ed_ward_graham
Starting Member
15 Posts |
Posted - 2008-12-09 : 11:49:09
|
| Sorry, sorry -- I edited my last post after seeing the responses but I wasn't quick enough! Will provide more data soon. |
 |
|
|
ed_ward_graham
Starting Member
15 Posts |
Posted - 2008-12-09 : 11:52:59
|
| Thanks for the tip, Charlie; I'll give that a try.Visakh16, in a stored procedure I am selecting a string field from a table which itself contains a SELECT statement. I then need to dynamically execute that statement (hence "arbitrary") and store the results somewhere, for further processing.All suggestions and alternatives gratefully received. |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-12-09 : 11:56:33
|
quote: Originally posted by ed_ward_graham Thanks for the tip, Charlie; I'll give that a try.Visakh16, in a stored procedure I am selecting a string field from a table which itself contains a SELECT statement. I then need to dynamically execute that statement (hence "arbitrary") and store the results somewhere, for further processing.All suggestions and alternatives gratefully received.
thats not a good approach. why are you storing sql statements itself inside a table? |
 |
|
|
ed_ward_graham
Starting Member
15 Posts |
Posted - 2008-12-09 : 11:59:46
|
| Sodeep, thanks for the OPENQUERY tip. Unfortunately, I don't think it'll work for me here, because I can't see a way of passing a parameter to the OPENQUERY(...) statement (in this case the "derived" select statement I am pulling back) without putting the whole thing into a string variable and EXEC'ing it, which then takes me back to the start ... (i.e., how to store and process the results). |
 |
|
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2008-12-09 : 12:05:13
|
quote: Thanks for the tip, Charlie; I'll give that a try.Visakh16, in a stored procedure I am selecting a string field from a table which itself contains a SELECT statement. I then need to dynamically execute that statement (hence "arbitrary") and store the results somewhere, for further processing.All suggestions and alternatives gratefully received.
OK in the spirit of helpful suggestions: That sounds insane.Assuming that you do mean completely arbitrary (with dynamic column names etc) then the results would be meaninless to store -- how do you plan to query the results when you can't tell what the column names will be?Also, how are you planning to cope when 2 ore more people execute the code at the same time (dynamic table names as well???)-- Do you really need completely arbitrary code? How are you planning on making this safe or are you happy that someone will be able to pass you a select statement that says'SELECT * FROM employee WHERE 1=1; DROP TABLE wages' You must have some sore of requirement to only query some data? I think you are going to have to give an example of a typical use case that you envisage for this. Otherwise the plan just sounds like a disaster waiting to happen.Sorry -- There's no point sugar coating this, the plan sounds terrible as you have described it.Charlie===============================================================Msg 3903, Level 16, State 1, Line 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
 |
|
|
ed_ward_graham
Starting Member
15 Posts |
Posted - 2008-12-09 : 12:07:19
|
quote: thats not a good approach. why are you storing sql statements itself inside a table?
It's part of a CMS for a database-driven web-site. The administrators can add new pages or new controls to existing pages, the content of which is stored in an XML field in the database. They may add a new table, say, with an accompanying SELECT statement that defines the data returned. For example, in the PageContent XML field of my table, I have things like:<PageContent><Control type="Literal"><b>This is literal HTML Content.</b></Control><Control type="GridView" selectStatement="SELECT Author, Title, Abstract FROM tblArticles" /></PageContent>The code then parses the XML, dynamically generates the corresponding controls and (in the case of the grid-view) fills them with data.Thanks again for your attention; it is much appreciated. |
 |
|
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2008-12-09 : 12:10:19
|
quote: It's part of a CMS for a database-driven web-site. The administrators can add new pages or new controls to existing pages, the content of which is stored in an XML field in the database. They may add a new table, say, with an accompanying SELECT statement that defines the data returned. For example, in the PageContent XML field of my table, I have things like:
The administrators (users) can add a new *table* to your schema? or an entry in some sort of lookup table? vastly different.Charlie===============================================================Msg 3903, Level 16, State 1, Line 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
 |
|
|
ed_ward_graham
Starting Member
15 Posts |
Posted - 2008-12-09 : 12:18:13
|
quote: OK in the spirit of helpful suggestions: That sounds insane.Assuming that you do mean completely arbitrary (with dynamic column names etc) then the results would be meaninless to store -- how do you plan to query the results when you can't tell what the column names will be?
Good point. The stored procedure needs to transform the arbitrary table (n rows by m columns) to a single-column table (n x 1), where the single column is the concatenation of all the arbitrary columns. I thought of using something likeSELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='<my_table_of_arbitrary_results>'with a cursor and building up another SELECT command with the column names stapled together with +s. A little complicated, I grant you! Basically, I'm trying to end up with a single cell that has *all* of the contents of the original n * m cells in it, separated with spaces. This will then be fed into an indexing program and used to make a site-searching tool.quote: Also, how are you planning to cope when 2 ore more people execute the code at the same time (dynamic table names as well???)-- Do you really need completely arbitrary code? How are you planning on making this safe or are you happy that someone will be able to pass you a select statement that says'SELECT * FROM employee WHERE 1=1; DROP TABLE wages' You must have some sore of requirement to only query some data? I think you are going to have to give an example of a typical use case that you envisage for this. Otherwise the plan just sounds like a disaster waiting to happen.
Users can't set the SELECT statements; only site administrators (or web-masters) can. It's part of a (admittedly very rough) hand-made CMS tool. |
 |
|
|
ed_ward_graham
Starting Member
15 Posts |
Posted - 2008-12-09 : 12:22:05
|
quote: The administrators (users) can add a new *table* to your schema? or an entry in some sort of lookup table? vastly different.
The latter -- sorry for the confusion. I meant "table" as in "HTML table".Thanks again for all your time: much appreciated! |
 |
|
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2008-12-09 : 12:38:11
|
I think you need to rethink this. Maybe some sort of Lookup table approach? Say something likeEXAMPLE_TABLE (holds data) ( [Id] (Identity primary key) , [ownerId] (foreign key) , [batchId] INT , [1] VARCHAR(4000) , [2] VARCHAR(4000) , [3] VARCHAR(4000) , [4] VARCHAR(4000) , [5] VARCHAR(4000) , [6] VARCHAR(4000) )LOOKUP_EXAMPLE_TABLE ( , [Id] (identity primary key) , [Name] VARCHAR(255) , [batchId] (foreign Key) (to Example Table) , [col1Alias] VARCHAR(255) , [col1DataType] , [col2Alias] VARCHAR(255) , [col2DataType] .... .... .... Then you don't have the problem of dynamic table or column names when storing or retreiving data. You write something that will parse the select statement into a form that can insert into the EXAMPLE table, and then store meta-data about the required column headers and datatypes in the lookup table.It's a lot of work - there's a reason that professional CMS tools cost so much. Also, it's not something I've got any direct experience with.Maybe your company should look into a prebuilt solution -- I understand there are free CRM tools though I have never used them. I only have experience with TeamTrack and Clarity, which may be overkill for your needs.Charlie===============================================================Msg 3903, Level 16, State 1, Line 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
 |
|
|
ed_ward_graham
Starting Member
15 Posts |
Posted - 2008-12-09 : 13:10:42
|
quote: Originally posted by Transact Charlie I think you need to rethink this. Maybe some sort of Lookup table approach? Say something like ...
Thanks for the advice, Charlie -- that would definitely have been a better way of doing it! Unfortunately, too much time has been spent already (isn't it always the way), so the quick-n-dirty solution you gave before is probably the way I need to go this time (with all disclaimers duly taken on board).So there really is no way of storing the results of EXEC(@ArbitrarySelectStatement) then? Seems amazing, although I can appreciate that perhaps there is a similar lack of legitimate reasons for doing so!Thanks to everyone for their help with this. |
 |
|
|
Next Page
|