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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.