简体   繁体   中英

T-SQL Create a view in a stored procedure using dynamic sql

I have a stored procedure which pivots query results and creates corresponding views. I'm stuck at the point where it actually creates views. Please see the code below

I've already tried with execute(), sp_executesql() .

If in an initial @query we don't have any variables then the following code works:

execute ('create view  AzureDataCatalog.temp AS ' + @query).

I have to make it work with variables.

DECLARE @iterator INT = 0


declare @n int = (
                SELECT COUNT(DISTINCT c.name)  AS [ColumnName]
                FROM    sys.views  v 
                        INNER JOIN sys.all_columns c ON v.object_id = c.object_id
                        INNER JOIN sys.schemas s ON v.schema_id = s.schema_id
                )

WHILE @iterator< @n
BEGIN

Declare @cols nvarchar(max)
Declare @query nvarchar(max)

Select @cols = stuff((select ','+QuoteName([ColumnName]) from 
(
    SELECT  DISTINCT c.name  AS [ColumnName]
    FROM    sys.views  v 
            INNER JOIN sys.all_columns c ON v.object_id = c.object_id
            INNER JOIN sys.schemas s ON v.schema_id = s.schema_id
    ORDER BY [ColumnName] 
    OFFSET @iterator ROWS
    FETCH NEXT 1000 ROWS ONLY
) tb

    for xml path('')),1,1,'')
Select @query = N' Select * from (
    Select [ColumnName], RowN = Row_Number() over (order by [ColumnName]) 
    FROM 
        (
            SELECT  DISTINCT c.name  AS [ColumnName]
            FROM    sys.views  v 
                INNER JOIN sys.all_columns c ON v.object_id = c.object_id
                INNER JOIN sys.schemas s ON v.schema_id = s.schema_id
            ORDER BY [ColumnName] 
            OFFSET @iterator ROWS
            FETCH NEXT 1000 ROWS ONLY
        ) tb
    ) a
    pivot (MAX([RowN]) for [ColumnName] in (' + @cols + ')) p '

Exec sp_executesql @query, N'@iterator INT', @iterator


DECLARE @iteratorName NVARCHAR(20)
SET @iteratorName = CONVERT(NVARCHAR(20), @iterator)

DECLARE @viewName VARCHAR(100)
DECLARE @sqlCommand NVARCHAR(100)
SET @viewName = 'temp' + @iteratorName

-- Check if the view exists
IF EXISTS(SELECT 1 FROM sys.views WHERE name = @viewName)
BEGIN
    SET @sqlCommand = 'SELECT ''Yes'''
    EXEC(@sqlCommand)

    execute ('drop view  AzureDataCatalog.temp' + @iteratorName)

    -- This code works, if there aren't any variables inside @query
    execute ('create view  AzureDataCatalog.temp' + @iteratorName +' AS ' + @query)
END
ELSE
BEGIN
    SET @sqlCommand = 'SELECT ''No'''
    EXEC(@sqlCommand)

    SET @sqlCommand = 'create view  AzureDataCatalog.temp' + @iteratorName +' AS ' + @query

    Exec sp_executesql @query, N'@iterator INT', @iterator
END

SET @iterator += 1024


/*Execute a Stored Procedure*/
END

Basically, I need to get the following code working:

DECLARE @sqlCommand NVARCHAR(100)
SET @sqlCommand = 'create view  AzureDataCatalog.temp' + @iteratorName +' AS ' + @query

Exec sp_executesql @query, N'@iterator INT', @iterator

But instead I get a following error

Msg 156, Level 15, State 1, Line 3
Incorrect syntax near the keyword 'view'.

To change identifiers, you need to munge the query string, which you seem to basically be doing. Just to be clear, store the view name you want in a string and use that in your code:

DECLARE @iteratorName NVARCHAR(20);
SET @iteratorName = CONVERT(NVARCHAR(20), @iterator);

DECLARE @viewName VARCHAR(100);
DECLARE @sqlCommand NVARCHAR(100);
SET @viewName = 'temp' + @iteratorName;

SET @sqlCommand = 'create view ' + @viewName + ' AS ' + @query;

EXEC sp_executesql @query;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM