如何使用变量执行创建视图
How to exec a create view with variables
我试图每次执行一个视图来处理运行。
我的代码有什么问题?为什么它不起作用?
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'.
附近的语法不正确
视图不带参数。如果您想在使用视图的时间点传递参数,您可以定义一个 table-valued user defined function。
但是,这里看起来您正试图从使用视图的位置单独设置参数。在这里,最好的选择可能是视图的某种形式的 "parameter table",例如:
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)
)
现在,上面的 table 可以包含 0 行或 1 行。我建议您只插入一行,然后让您的存储过程针对它发出 UPDATE
。
现在,在视图中,您可以简单地连接到此 table,然后将这些列值与其他 tables1[=36= 的列进行比较].您无需在参数值更改时删除并重新创建它。
我不知道为什么 @Phase
被标记为 OUTPUT
。
1或者 CROSS JOIN
并继续在 WHERE
或 INNER JOIN
中进行实际比较并移动 some/all ON
子句中的比较。
我猜,你想要这个 SP。
CREATE PROCEDURE dbo.MTBFAlterView @PressType nvarchar(50), @TestName nvarchar(50)
, @PressName nvarchar(50), @Phase nvarchar(50)
AS
--Failure Report Table
begin
DECLARE @ViewDROP nvarchar(MAX) = N'DROP VIEW [dbo].[UV_filteredLogins]' -- 'N' has been added
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= '''+@Phase +''' and press.PressName= '''+ @PressName +'''
and pressType.Type_Description= '''+@PressType +
/*Parameter's values are applied in WHERE condition*/
''' 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
)';
EXEC sp_executesql @STMT -- View will be created.
select * from UV_filteredLogins -- Call it.
--EXEC sp_executesql @ViewDROP -- Drop query of view.
end
exec dbo.MTBFAlterView 'HP Indigo 10000', 'Go Green'
, 'MR-193','Test'
-- If you call this, then view is created and followed by 'SELECT'
如果您希望传递的参数是 VIEW
定义中的文字值,那么这就是您想要构建它的方式:
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 安全。因此,例如,像 "don't" 这样的值将被解析为 'don''t'
。这避免了在您的 SP 中注入,这在使用动态 SQL.
时非常重要
我试图每次执行一个视图来处理运行。 我的代码有什么问题?为什么它不起作用?
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'.
附近的语法不正确视图不带参数。如果您想在使用视图的时间点传递参数,您可以定义一个 table-valued user defined function。
但是,这里看起来您正试图从使用视图的位置单独设置参数。在这里,最好的选择可能是视图的某种形式的 "parameter table",例如:
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)
)
现在,上面的 table 可以包含 0 行或 1 行。我建议您只插入一行,然后让您的存储过程针对它发出 UPDATE
。
现在,在视图中,您可以简单地连接到此 table,然后将这些列值与其他 tables1[=36= 的列进行比较].您无需在参数值更改时删除并重新创建它。
我不知道为什么 @Phase
被标记为 OUTPUT
。
1或者 CROSS JOIN
并继续在 WHERE
或 INNER JOIN
中进行实际比较并移动 some/all ON
子句中的比较。
我猜,你想要这个 SP。
CREATE PROCEDURE dbo.MTBFAlterView @PressType nvarchar(50), @TestName nvarchar(50)
, @PressName nvarchar(50), @Phase nvarchar(50)
AS
--Failure Report Table
begin
DECLARE @ViewDROP nvarchar(MAX) = N'DROP VIEW [dbo].[UV_filteredLogins]' -- 'N' has been added
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= '''+@Phase +''' and press.PressName= '''+ @PressName +'''
and pressType.Type_Description= '''+@PressType +
/*Parameter's values are applied in WHERE condition*/
''' 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
)';
EXEC sp_executesql @STMT -- View will be created.
select * from UV_filteredLogins -- Call it.
--EXEC sp_executesql @ViewDROP -- Drop query of view.
end
exec dbo.MTBFAlterView 'HP Indigo 10000', 'Go Green'
, 'MR-193','Test'
-- If you call this, then view is created and followed by 'SELECT'
如果您希望传递的参数是 VIEW
定义中的文字值,那么这就是您想要构建它的方式:
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 安全。因此,例如,像 "don't" 这样的值将被解析为 'don''t'
。这避免了在您的 SP 中注入,这在使用动态 SQL.