Microsoft SQL Server의 뷰에 매개 변수를 전달할 수 있습니까?
create view
다음과 같은 방법으로 시도했지만 작동하지 않습니다.
create or replace view v_emp(eno number) as select * from emp where emp_id=&eno;
Parameters are out of the discussion
너무 대담한 진술. 반례
Microsoft SQL Server의 뷰에 매개 변수를 전달할 수 있습니까?
create view
다음과 같은 방법으로 시도했지만 작동하지 않습니다.
create or replace view v_emp(eno number) as select * from emp where emp_id=&eno;
Parameters are out of the discussion
너무 대담한 진술. 반례
답변:
이미 언급했듯이 할 수 없습니다.
가능한 해결책은 다음과 같은 저장 함수를 구현하는 것입니다.
CREATE FUNCTION v_emp (@pintEno INT)
RETURNS TABLE
AS
RETURN
SELECT * FROM emp WHERE emp_id=@pintEno;
이를 통해 다음과 같이 일반보기로 사용할 수 있습니다.
SELECT * FROM v_emp(10)
불행히도 원하는 것을 달성하는 두 가지 방법이 있습니다.
원하는 매개 변수를 사용하고 쿼리 결과를 반환하는 테이블 값 사용자 정의 함수를 만들 수 있습니다
또는 거의 동일한 작업을 수행 할 수 있지만 사용자 정의 함수 대신 저장 프로 시저를 만들 수 있습니다.
예를 들어
저장 프로시 저는 다음과 같습니다
CREATE PROCEDURE s_emp
(
@enoNumber INT
)
AS
SELECT
*
FROM
emp
WHERE
emp_id=@enoNumber
또는 사용자 정의 함수는 다음과 같습니다
CREATE FUNCTION u_emp
(
@enoNumber INT
)
RETURNS TABLE
AS
RETURN
(
SELECT
*
FROM
emp
WHERE
emp_id=@enoNumber
)
Mladen Prajdic가 말했듯이 당신은 할 수 없습니다. 뷰를 테이블 또는 테이블 조합에서 "정적 필터"로 생각하십시오. 예를 들어 뷰는 테이블을 결합 할 수 Order
및 Customer
당신의 행의 새로운 "테이블"을 얻을 수 있도록 Order
고객의 이름과 고객 번호 (테이블의 조합)을 포함하는 새로운 컬럼과 함께. 또는 Order
테이블 에서 처리되지 않은 주문 만 선택하는 뷰를 작성할 수 있습니다 (정적 필터).
그런 다음 다른 "정상"테이블에서 선택하는 것처럼보기에서 선택합니다. "정적되지 않은"모든 필터링은보기 외부에서 수행해야합니다 (예 : "밀러라는 고객의 모든 주문 가져 오기"또는 "처리되지 않은 주문 가져 오기) 12 월 24 일에 나왔습니다 ").
일반적으로 뷰는 매개 변수화되지 않습니다. 그러나 항상 일부 매개 변수를 주입 할 수 있습니다. 예를 들어 세션 컨텍스트 를 사용하는 경우 :
CREATE VIEW my_view
AS
SELECT *
FROM tab
WHERE num = SESSION_CONTEXT(N'my_num');
기도:
EXEC sp_set_session_context 'my_num', 1;
SELECT * FROM my_view;
그리고 또 다른:
EXEC sp_set_session_context 'my_num', 2;
SELECT * FROM my_view;
Oracle에도 동일하게 적용됩니다 (물론 컨텍스트 함수의 구문이 다릅니다).
보기에 매개 변수가 필요한 이유는 무엇입니까? 당신은 WHERE
절을 사용할 수 있습니다 .
create view v_emp as select * from emp ;
쿼리가 작업을 수행해야합니다.
select * from v_emp where emp_id=&eno;
WHERE
대신 테이블에 대한 성능이 크게 향상 되는 WHERE
경우가 있습니다.
저장 프로시 저나 함수없이 해킹하는 방법은 데이터베이스에 Id, Param1, Param2 등의 설정 테이블을 만드는 것입니다. Id = 1, Param1 = 0, Param2 값을 포함하는 행을 해당 테이블에 삽입하십시오. = 0 등입니다. 그런 다음 뷰에서 해당 테이블에 조인을 추가하여 원하는 효과를 만들고 뷰를 실행하기 전에 설정 테이블을 업데이트 할 수 있습니다. 여러 사용자가 설정 테이블을 업데이트하고 동시에보기를 실행하는 경우 문제가 발생할 수 있지만 그렇지 않으면 제대로 작동합니다. 다음과 같은 것 :
CREATE VIEW v_emp
AS
SELECT *
FROM emp E
INNER JOIN settings S
ON S.Id = 1 AND E.emp_id = S.Param1
아니요, 뷰는 테이블에서 SELECTing과 다르게 쿼리되지 않습니다.
원하는 것을 수행하려면 하나 이상의 매개 변수와 함께 테이블 반환 사용자 정의 함수를 사용하십시오.
입력 매개 변수로 스토어드 프로 시저를 작성한 다음 해당 스토어드 프로 시저를 사용하여 뷰에서 결과 세트를 얻을 수 있습니다. 아래 예를 참조하십시오.
저장 프로시 저는
CREATE PROCEDURE [dbo].[sp_Report_LoginSuccess] -- [sp_Report_LoginSuccess] '01/01/2010','01/30/2010'
@fromDate datetime,
@toDate datetime,
@RoleName varchar(50),
@Success int
as
If @RoleName != 'All'
Begin
If @Success!=2
Begin
--fetch based on true or false
Select * from vw_Report_LoginSuccess
where logindatetime between dbo.DateFloor(@fromDate) and dbo.DateSieling(@toDate)
And RTrim(Upper(RoleName)) = RTrim(Upper(@RoleName)) and Success=@Success
End
Else
Begin
-- fetch all
Select * from vw_Report_LoginSuccess
where logindatetime between dbo.DateFloor(@fromDate) and dbo.DateSieling(@toDate)
And RTrim(Upper(RoleName)) = RTrim(Upper(@RoleName))
End
End
Else
Begin
If @Success!=2
Begin
Select * from vw_Report_LoginSuccess
where logindatetime between dbo.DateFloor(@fromDate) and dbo.DateSieling(@toDate)
and Success=@Success
End
Else
Begin
Select * from vw_Report_LoginSuccess
where logindatetime between dbo.DateFloor(@fromDate) and dbo.DateSieling(@toDate)
End
End
결과 집합을 얻을 수있는 관점은
CREATE VIEW [dbo].[vw_Report_LoginSuccess]
AS
SELECT '3' AS UserDetailID, dbo.tblLoginStatusDetail.Success, CONVERT(varchar, dbo.tblLoginStatusDetail.LoginDateTime, 101) AS LoginDateTime,
CONVERT(varchar, dbo.tblLoginStatusDetail.LogoutDateTime, 101) AS LogoutDateTime, dbo.tblLoginStatusDetail.TokenID,
dbo.tblUserDetail.SubscriberID, dbo.aspnet_Roles.RoleId, dbo.aspnet_Roles.RoleName
FROM dbo.tblLoginStatusDetail INNER JOIN
dbo.tblUserDetail ON dbo.tblLoginStatusDetail.UserDetailID = dbo.tblUserDetail.UserDetailID INNER JOIN
dbo.aspnet_UsersInRoles ON dbo.tblUserDetail.UserID = dbo.aspnet_UsersInRoles.UserId INNER JOIN
dbo.aspnet_Roles ON dbo.aspnet_UsersInRoles.RoleId = dbo.aspnet_Roles.RoleId
WHERE (dbo.tblLoginStatusDetail.Success = 0)
UNION all
SELECT dbo.tblLoginStatusDetail.UserDetailID, dbo.tblLoginStatusDetail.Success, CONVERT(varchar, dbo.tblLoginStatusDetail.LoginDateTime, 101)
AS LoginDateTime, CONVERT(varchar, dbo.tblLoginStatusDetail.LogoutDateTime, 101) AS LogoutDateTime, dbo.tblLoginStatusDetail.TokenID,
dbo.tblUserDetail.SubscriberID, dbo.aspnet_Roles.RoleId, dbo.aspnet_Roles.RoleName
FROM dbo.tblLoginStatusDetail INNER JOIN
dbo.tblUserDetail ON dbo.tblLoginStatusDetail.UserDetailID = dbo.tblUserDetail.UserDetailID INNER JOIN
dbo.aspnet_UsersInRoles ON dbo.tblUserDetail.UserID = dbo.aspnet_UsersInRoles.UserId INNER JOIN
dbo.aspnet_Roles ON dbo.aspnet_UsersInRoles.RoleId = dbo.aspnet_Roles.RoleId
WHERE (dbo.tblLoginStatusDetail.Success = 1) AND (dbo.tblUserDetail.SubscriberID LIKE N'P%')
함수를 사용하지 않으려면 다음과 같이 사용할 수 있습니다
-- VIEW
CREATE VIEW [dbo].[vwPharmacyProducts]
AS
SELECT PharmacyId, ProductId
FROM dbo.Stock
WHERE (TotalQty > 0)
-- Use of view inside a stored procedure
CREATE PROCEDURE [dbo].[usp_GetProductByFilter]
( @pPharmacyId int ) AS
IF @pPharmacyId = 0 BEGIN SET @pPharmacyId = NULL END
SELECT P.[ProductId], P.[strDisplayAs] FROM [Product] P
WHERE (P.[bDeleted] = 0)
AND (P.[ProductId] IN (Select vPP.ProductId From vwPharmacyProducts vPP
Where vPP.PharmacyId = @pPharmacyId)
OR @pPharmacyId IS NULL
)
그것이 도움이되기를 바랍니다.
지금까지 보지 못한 옵션은 다음과 같습니다.
보기에 제한하려는 열을 추가하십시오.
create view emp_v as (
select emp_name, emp_id from emp;
)
select emp_v.emp_name from emp_v
where emp_v.emp_id = (id to restrict by)
뷰는 매개 변수가 포함 된 일부 외부 테이블을 참조 할 수 있습니다.
다른 사람들이 언급했듯이 SQL Server의 뷰는 외부 입력 매개 변수를 가질 수 없습니다. 그러나 CTE를 사용하여 뷰에서 변수를 쉽게 위조 할 수 있습니다. SQL Server 버전에서 테스트를 실행할 수 있습니다.
CREATE VIEW vwImportant_Users AS
WITH params AS (
SELECT
varType='%Admin%',
varMinStatus=1)
SELECT status, name
FROM sys.sysusers, params
WHERE status > varMinStatus OR name LIKE varType
SELECT * FROM vwImportant_Users
산출량 :
status name
12 dbo
0 db_accessadmin
0 db_securityadmin
0 db_ddladmin
또한 통해 JOIN
WITH params AS ( SELECT varType='%Admin%', varMinStatus=1)
SELECT status, name
FROM sys.sysusers INNER JOIN params ON 1=1
WHERE status > varMinStatus OR name LIKE varType
또한 통해 CROSS APPLY
WITH params AS ( SELECT varType='%Admin%', varMinStatus=1)
SELECT status, name
FROM sys.sysusers CROSS APPLY params
WHERE status > varMinStatus OR name LIKE varType
아직 시도하지 않았다는 아이디어가 있습니다. 넌 할 수있어:
CREATE VIEW updated_customers AS
SELECT * FROM customer as aa
LEFT JOIN customer_rec as bb
ON aa.id = bb.customer_id
WHERE aa.updated_at between (SELECT start_date FROM config WHERE active = 1)
and (SELECT end_date FROM config WHERE active = 1)
매개 변수가 구성 테이블에 저장되고 변경됩니다.
나는 다음과 같이 내 요구에 대한이 작업을 깨달았습니다.
set nocount on;
declare @ToDate date = dateadd(month,datediff(month,0,getdate())-1,0)
declare @year varchar(4) = year(@ToDate)
declare @month varchar(2) = month(@ToDate)
declare @sql nvarchar(max)
set @sql = N'
create or alter view dbo.wTempLogs
as
select * from dbo.y2019
where
year(LogDate) = ''_year_''
and
month(LogDate) = ''_month_'' '
select @sql = replace(replace(@sql,'_year_',@year),'_month_',@month)
execute sp_executesql @sql
declare @errmsg nvarchar(max)
set @errMsg = @sql
raiserror (@errMsg, 0,1) with nowait