views:

399

answers:

2

I would like to create a SP or UDF where I supply a table and column name as a parameter and it does something to that target. I'm using Sql Server 2005

Trivial Example of what I'm trying to accomplish:

CREATE FUNCTION Example (@TableName AS VARCHAR(100))
RETURNS TABLE
AS
BEGIN
    SELECT * 
    INTO #temp
    FROM @TableName

    RETURN #temp
END

The example is just something trivial to illustrate what I'm trying to accomplish in terms of passing the Table name as a parameter.

Is this possible to do w/o concatinating strings and calling the EXEC function?

Ultimately, I'm trying to convert the answer from this question into something reusable.

+2  A: 

This reeks of SQL injection. You would still need to use EXEC to do this.

JonH
Yea I know..that's part of the reason why I'm hoping there's a way to NOT use the EXEC. May just opt to not turn what I need into a SP or UDF if it's not possible.
JamesEggers
It is not possible to pass a table name as a parameter without using EXEC. Its poor coding practice. My advice to you is to create a full blown stored procedure with parameters rather then trying to dynamically create SQL. I hate dynamic SQL for reasons like this. Even if it means you need to create multiple stored procedures it's the safer cleaner route to go.
JonH
@JonH I hate dynamic sql too. This is a case where I'm trying to take the answer to this question (http://stackoverflow.com/questions/1591325/concatenating-records-in-a-single-column-without-looping) and convert it into something reusable.
JamesEggers
@James: FOR XML PATH('') in a subselect is probably your best bet. Use STUFF to remove the leading delimiters, and watch out for funky characters.
Peter
That, or a CLR UDA.
Peter
Looks like I won't be making this a UDF or SP then. Not worth the risk. Thanks
JamesEggers
+2  A: 

No. Can't do it. Sadly, there is no macro pre-complier in T-SQL. The closest you'll get is SQLCMD mode, but that's only for scripts, can't use it in object definitions.

Are you doing the same thing to the table each time?

You could dynamically redefine a synonym, but that still requires an EXEC and you lose concurrency. You could serialize execution with a queue, but at that point you may be better off w/ plain old dynamic SQL.

You might try temporary tables, not passed in as a variable, but created in the parent connection or calling procedure. eg.

create proc #proc as
select * from #table
go

create table #table (col1 int)
insert #table values (1)
insert #table values (2)
insert #table values (3)
go

exec #proc
go

For more ways to share data between stored procedures, see here: http://www.sommarskog.se/share%5Fdata.html

Peter
Looks like I won't be making this a UDF or SP then. Not worth the risk. Thanks
JamesEggers
Try a CLR UDA, if you have cooperation of your DBA. Other techniques here: http://www.simple-talk.com/sql/t-sql-programming/concatenating-row-values-in-transact-sql/
Peter