Monardo
Monardo

Reputation: 23

How to represent dynamic query in SQL Server view

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

Answers (3)

J.D.
J.D.

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

J.D.
J.D.

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

Utsav
Utsav

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

Related Questions