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)
残念ながら、ビューを使用してどちらも実行できない2つの方法があります。
必要なパラメーターを取り、クエリ結果を返すテーブル値のユーザー定義関数を作成できます。
または、ほとんど同じことを実行できますが、ユーザー定義関数の代わりにストアドプロシージャを作成します。
例えば
ストアドプロシージャは次のようになります
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
番号。次に、パラメーターを渡すことができるユーザー定義関数を使用する必要がある場合。
いいえ、ビューのクエリはテーブルからのSELECTと同じです。
やりたいことを行うには、1つ以上のパラメーターを持つテーブル値のユーザー定義関数を使用します
入力パラメータを使用してストアドプロシージャを記述し、そのストアドプロシージャを使用してビューから結果セットを取得できます。以下の例を参照してください。
ストアドプロシージャは
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
)
それが役に立てば幸い
ビューは、パラメーターを含む外部テーブルを参照できます。
他の人が述べたように、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