0

Creating a user-defined table-valued function which should return select union all dynamic query.

I have table tbl_tablesinfo which contains table names tbl1, tbl2, tbl3, etc. in all around 3000 table names.

I don't want to create view but function which should return select * from all tables by doing union all.

My attempt:

CREATE FUNCTION udf_alldata()
RETURNS TABLE
AS
BEGIN
    DECLARE @Var VARCHAR(MAX) = ''

    SELECT 
        @Var = STUFF((SELECT ' SELECT * FROM [' + tbl.TableNames + '] UNION ALL'
                      FROM [TestDB].SYS.TABLES tb 
                      INNER JOIN [TestDB].dbo.[tbl_tablesinfo] tbl ON tb.name = tbl.TableNames
                      FOR XML PATH('')), 1, 1, '');

    SET @var = LEFT(@var, LEN(@var) - 10);

    EXEC @var 

    RETURN
END

I'm getting an error:

Incorrect syntax near 'BEGIN'.

Reason for doing this is creating view with 3k tables is getting slow and taking around 30 min of time, so I am looking for an alternative by creating function.

1
  • 1
    By saying returns table without defining the table you are creating an inline table valued function which can only have a return select in it. It you want a regular table valued function you need to define the return table. Please consult the docs. Commented Nov 5, 2019 at 5:52

2 Answers 2

2

In the docs is clear said, that:

User-defined functions cannot make use of dynamic SQL or temp tables. Table variables are allowed.

which means that you need to use a stored procedure and this is not bad as you can still insert the data in table if you want:

INSERT INTO @Table
EXEC [dbo].[stored_procedured_name]

INSERT INTO #Table
EXEC [dbo].[stored_procedured_name]

So, in your case you will have:

CREATE PROCEDURE udf_alldata
AS
BEGIN
    DECLARE @Var VARCHAR(MAX) = ''

    SELECT 
        @Var = STUFF((SELECT ' SELECT * FROM [' + tbl.TableNames + '] UNION ALL'
                      FROM [TestDB].SYS.TABLES tb 
                      INNER JOIN [TestDB].dbo.[tbl_tablesinfo] tbl ON tb.name = tbl.TableNames
                      FOR XML PATH('')), 1, 1, '');

    SET @var = LEFT(@var, LEN(@var) - 10);

    EXEC sp_executesql @var 

    RETURN
END

Note, actually you can execute dynamic T-SQL in function but this is special case using SQL CLR. I can show you how to do this, but it will be better to stuck with the stored procedure.

Sign up to request clarification or add additional context in comments.

Comments

0
  1. You can't use Dynamic Query in SQL Function...
  2. Functions can return only Scalar Values, or Tables...
  3. Instead you can use Stored Procedure...

1 Comment

While this is technically correct it's not much of a quality answer... this would be better off as a comment.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.