Reputation: 2989
I created a function that will return a varchar
CREATE FUNCTION dbo.Test
(
@i INT
)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE @it VARCHAR(MAX)
SET @it = 'INSERT INTO @Test
VALUES (1)
'
RETURN @it
END
I tried to used that function in the query below but got an error.
DECLARE @d VARCHAR(MAX)
DECLARE @Test TABLE
(
i INT
)
SET @d = dbo.Test(1)
SELECT @d
EXEC (@d)
SELECT * FROM @Test
Why function is not working in table variable?
How to make it work?
Upvotes: 0
Views: 544
Reputation: 2419
Try this: If we try to use Select from @test from outside its declaration scope then it will not work. Hence, it has been SET in @it.
CREATE FUNCTION [dbo].[Test]
(
@i INT
)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE @it VARCHAR(MAX)
SET @it = 'DECLARE @Test TABLE(i INT); INSERT INTO @Test VALUES (1); SELECT * FROM @Test'
RETURN @it
END
DECLARE @Test TABLE
(
i INT
)
DECLARE @d VARCHAR(MAX)
SET @d = dbo.Test(1)
SELECT @d
INSERT INTO @Test
EXEC (@d)
Upvotes: 1
Reputation: 48826
If your goal is to have a function that builds one or more insert statements that can then be executed to populate a table, that cannot work using a Table Variable as those are not available in other scopes (i.e. sub-process or parent-process scopes). The only way to do something like this is:
#Temp
)EXEC
).Example:
CREATE FUNCTION dbo.Test
(
@i INT
)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE @it VARCHAR(MAX);
SET @it = 'INSERT INTO #Test (Col1)
VALUES (' + CONVERT(VARCHAR(20), @i) + ');
'
RETURN @it;
END;
And use in this manner:
DECLARE @SQL VARCHAR(MAX);
--DROP TABLE #Test;
CREATE TABLE #Test
(
Col1 INT
);
SET @SQL = dbo.Test(1);
SET @SQL += dbo.Test(55);
SELECT @SQL;
EXEC (@SQL);
SELECT * FROM #Test;
Upvotes: 0
Reputation: 77876
Try doing it this way by using a temporary table instead of table variable since table variable won't be accessible as already pointed by others in comment. [Not Tested]
CREATE FUNCTION dbo.Test
(
@i INT
)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE @it VARCHAR(MAX)
SET @it = 'CREATE TABLE #Test(i INT); INSERT INTO #Test
VALUES (1)'
RETURN @it
END
Then call your function like
DECLARE @d VARCHAR(MAX)
SET @d = dbo.Test(1)
SELECT @d
EXEC (@d)
SELECT * FROM #Test
Upvotes: 0
Reputation: 7692
Dynamic SQL executes in a separate context, in which your variables (including table ones) are unavailable.
The nearest thing to what you are trying to do is, probably, this:
insert into @Test
exec(@d);
whereas function will return only the select
part.
Don't forget, though, that in Microsoft SQL Server you cannot nest insert into ... exec
statements.
Upvotes: 0