Reputation: 23
I have the following SQL code:
DECLARE @i INT = 1;
DECLARE @sql_code varchar(max) = '';
DECLARE @repeats INT = 4;
WHILE @i <= @repeats
BEGIN
SET @sql_code = @sql_code+'SELECT ''foo'+cast(@i as varchar)+''' as bar UNION ALL '
SET @i = @i + 1
END;
SET @sql_code = LEFT(@sql_code,LEN(@sql_code) - 10)
exec (@sql_code)
,which when run in SSMS produces this:
bar
----
foo1
foo2
foo3
foo4
How can I reproduce the same result as view (dynamically)?
I know you can't use declarations in view, but could it be done through stored procedure or function?
Upvotes: 0
Views: 351
Reputation: 1023
Also, despite my informational answer, you can of course use a stored procedure alone if that's sufficient for your use case.
could it be done through stored procedure
Sure, just wrap a stored procedure around your code:
CREATE PROCEDURE dbo.SomeStoredProcedure
AS
DECLARE @i INT = 1;
DECLARE @sql_code NVARCHAR(MAX) = '';
DECLARE @repeats INT = 4;
WHILE @i <= @repeats
BEGIN
SET @sql_code = @sql_code+'SELECT ''foo'+cast(@i as varchar)+''' as bar UNION ALL '
SET @i = @i + 1
END;
SET @sql_code = LEFT(@sql_code,LEN(@sql_code) - 10)
EXEC sp_executesql @sql_code
Note I changed the last line of your code to use sp_executesql
because it minimizes your risk for SQL injection issues. You should always use that procedure for dynamic SQL execution instead of directly executing your SQL string.
Upvotes: 0
Reputation: 1023
Actually, despite what Utsav's good answer says, you can do anything if you put your mind to it. 😉
While this is generally not recommended (this answer is for informational purposes), there are certain use cases where it makes sense to use OPENQUERY()
inside a View. OPENQUERY()
allows you to execute raw SQL against a remote or local SQL Server. Either in the raw SQL itself, or probably more organized in a stored procedure, there's essentially no limitations on the queries you can run, including dynamic SQL.
Example:
CREATE PROCEDURE dbo.RunSomeDynamicSQL
AS
DECLARE @DynamicSQL NVARCHAR(MAX) =
'
SELECT 1 AS Foobar;
';
EXEC sp_executesql @DynamicSQL;
GO
CREATE VIEW dbo.SomeViewThatExecutesDynamicSQL
AS
SELECT Foobar
FROM OPENQUERY
(
LocalServerName,
'
EXEC YourDatabaseName.dbo.RunSomeDynamicSQL
WITH RESULT SETS
((
Foobar INT
));
'
);
GO
SELECT Foobar
FROM dbo.SomeViewThatExecutesDynamicSQL;
You'll notice I'm using the WITH RESULT SETS
keyword when executing my procedure inside of OPENQUERY()
. This is because OPENQUERY()
needs to know the shape of the result set from the executing query. This is one way to describe that when executing a procedure.
One use case for using OPENQUERY()
in a View is so you can maximize your ability to performance tune your query (e.g. inside a stored procedure) without losing consumability of the database object.
One important fact about using OPENQUERY()
is that the SQL Server Engine always estimates the cardinality of the results to be 10,000 rows. This means if your result set is much larger than 10,000 rows, for example 10 million rows, then you may not get the most optimal execution plan to serve your query.
Upvotes: 0
Reputation: 119
You can't use dynamic sql inside a view. But yes you can create table valued User-Defined functions as mentioned in this post.
Link to the post: https://social.msdn.microsoft.com/Forums/sqlserver/en-US/3cdeda6c-af19-46e9-b89f-e575fecd475b/dynamic-query-in-view?forum=transactsql
Answer by Gavin Campbell should give you the idea of what can be done.
Note : For more information on Table valued User-Defined Functions: Visit this documentation: https://learn.microsoft.com/en-us/previous-versions/sql/sql-server-2008-r2/ms191165(v=sql.105)?redirectedfrom=MSDN
Upvotes: 2