如何使用变量执行创建视图

时间:2019-01-17 09:58:33

标签: sql sql-server view sp-executesql

我试图在每次程序运行时执行一个视图。 我的代码有什么问题?为什么它不起作用?

CREATE PROCEDURE dbo.MTBFAlterView @PressType nvarchar(50), @TestName nvarchar(50), @PressName nvarchar(50), @Phase nvarchar(50)
AS
--Failure Report Table
DECLARE @ViewDROP nvarchar(MAX) = 'DROP VIEW [dbo].[UV_filteredLogins]'
DECLARE @ParmDefinition nvarchar(500);  
 DECLARE @STMT AS NVARCHAR(MAX) = N'
                                    Create VIEW [dbo].[UV_filteredLogins]
                                    as
                                    SELECT logins.[ID]
                                        ,[Test_ID]
                                        ,phase.Phase_Name
                                        ,press.PressName
                                        ,pressType.Type_Description as PressType
                                        ,[Operator]
                                        ,[LoginDate]
                                        ,[LogoutDate]
                                        ,DATEDIFF(MINUTE,LoginDate,LogoutDate) as TimeDiff
                                    FROM [TDM_Analysis].[dbo].[Logins] as logins join [TDM_Analysis].[dbo].[Presses] as press on logins.Press_ID=press.ID 
                                    join [TDM_Analysis].[dbo].[Phases] as phase on logins.Phase_ID=phase.ID 
                                    join [TDM_Analysis].[dbo].[PressTypes] as pressType on pressType.ID=press.PressType_ID
                                    join [TDM_Analysis].[dbo].[Tests] as test on logins.Test_ID=test.ID
                                    where phase.Phase_Name= @Phase1 and press.PressName= @PressName1 and pressType.Type_Description=@PressType1 and [Test_ID]=TestName1 and logoutDate is not null
                                        and Operator in (SELECT au.Email
                                                        FROM [UsersAuthorization].[dbo].[RolesMembers] as RM join [UsersAuthorization].[dbo].[ApplicationUsers] as AU on RM.ApplicationUserID=au.ID
                                                        where rm.roleid=1)';
    SET @ParmDefinition=N'@PressType1 nvarchar(50), @TestName1 nvarchar(50), @PressName1 nvarchar(50), @Phase1 nvarchar(50) OUTPUT'; 
    --EXEC sp_executesql @ViewDROP
   EXEC sp_executesql @STMT, @ParmDefinition, @PressType1 = @PressType, @TestName1=@TestName, @PressName1=@PressName, @Phase1=@Phase OUTPUT;



   exec dbo.MTBFAlterView @PressType='HP Indigo 10000', @TestName='Go Green', @PressName='MR-193', @Phase='Test'

我的结果是: 消息156,第15层,州1,第34行 关键字“ VIEW”附近的语法不正确。

3 个答案:

答案 0 :(得分:2)

视图不带参数。如果您想在使用视图的时间点传递参数,则可以定义一个table-valued user defined function

但是,这里看起来您正在尝试从使用视图的地方分别设置 参数。在这里,最佳选择可能是视图的某种形式的“参数表”,例如:

CREATE TABLE UV_filteredLogins_parms (
    Lock char(1) not null,
    constraint CK_UV_filteredLogins_Locked CHECK (Lock = 'X'),
    constraint PK_UV_filteredLogins PRIMARY KEY (Lock),
    PressType nvarchar(50),
    TestName nvarchar(50),
    PressName nvarchar(50),
    Phase nvarchar(50)
)

现在,上表可以包含0行或1行。我建议您只插入一行,然后使您的存储过程对它发出UPDATE

现在,在视图内部,您可以简单地连接到该表,然后将这些列值与其他表中的列进行比较 1 。只要参数值更改,您就无需删除并重新创建它。

我不知道为什么@Phase被标记为OUTPUT


1 CROSS JOIN,然后继续在WHEREINNER JOIN中进行实际比较,并将部分/全部比较移至{{ 1}}子句。

答案 1 :(得分:0)

我想,您需要这个SP。

Cluster.set_core_connections_per_host()

答案 2 :(得分:0)

如果您希望传递的参数是VIEW定义中的literatl值,那么这就是您要构建的方法:

CREATE PROCEDURE dbo.MTBFAlterView @PressType nvarchar(50), @TestName nvarchar(50), @PressName nvarchar(50), @Phase nvarchar(50)
AS BEGIN

    IF EXISTS (SELECT 1 FROM sys.objects WHERE [name] = 'UV_filteredLogins')
        DROP VIEW UV_filteredLogins;

    DECLARE @SQL nvarchar(MAX) = N'
CREATE VIEW [dbo].[UV_filteredLogins]
AS
    SELECT logins.[ID],
           [Test_ID],
           phase.Phase_Name,
           press.PressName,
           pressType.Type_Description AS PressType,
           [Operator],
           [LoginDate],
           [LogoutDate],
           DATEDIFF(MINUTE, LoginDate, LogoutDate) AS TimeDiff
    FROM [TDM_Analysis].[dbo].[Logins] logins
         JOIN [TDM_Analysis].[dbo].[Presses] press ON logins.Press_ID = press.ID
         JOIN [TDM_Analysis].[dbo].[Phases] phase ON logins.Phase_ID = phase.ID
         JOIN [TDM_Analysis].[dbo].[PressTypes] pressType ON pressType.ID = press.PressType_ID
         JOIN [TDM_Analysis].[dbo].[Tests] test ON logins.Test_ID = test.ID
    WHERE phase.Phase_Name = ' + QUOTENAME(@Phase,N'''') + N'
      AND press.PressName = ' + QUOTENAME(@PressName,N'''') + N'
      AND pressType.Type_Description = ' + QUOTENAME(@PressType,N'''') + N'
      AND [Test_ID] = TestName1
      AND logoutDate IS NOT NULL
      AND Operator IN (SELECT AU.Email
                       FROM [UsersAuthorization].[dbo].[RolesMembers] RM
                            JOIN [UsersAuthorization].[dbo].[ApplicationUsers] AU ON RM.ApplicationUserID = AU.ID
                       WHERE RM.roleid = 1);';

    EXEC sp_executesql @SQL;
END
GO

请注意此处使用QUOTENAME。通过在生成值时适当地引用值,可以确保动态SQL的安全。因此,例如,“ do n't”之类的值将被解析为'don''t'。这样可以避免在SP中注入,这在使用动态SQL时非常重要。