web-dev-qa-db-ja.com

SQLのビューにパラメーターを渡すことはできますか?

Microsoft SQL Serverのビューにパラメーターを渡すことはできますか?

私は次の方法でcreate viewを試みましたが、うまくいきません:

create or replace view v_emp(eno number) as select * from emp where emp_id=&eno;
112
arunachalam

すでに述べたように、できません。

可能な解決策は、次のようなストアド関数を実装することです。

CREATE FUNCTION v_emp (@pintEno INT)
RETURNS TABLE
AS
RETURN
   SELECT * FROM emp WHERE emp_id=@pintEno;

これにより、通常のビューとして使用できます。

SELECT * FROM v_emp(10)
113
Alex Bagnolini

残念ながら、ビューを使用して行うことはできませんが、残念ながら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
)
31
Gavin

いいえ、できません。MladenPrajdicが言ったように。ビューは、テーブルまたはテーブルの組み合わせの「静的フィルター」と考えてください。たとえば、ビューはテーブルOrderCustomerを組み合わせることができるため、Orderから新しい行の「テーブル」と、顧客の名前と顧客番号を含む新しい列(テーブルの組み合わせ)を取得できます。または、Orderテーブル(静的フィルター)から未処理の注文のみを選択するビューを作成することもできます。

次に、他の「通常の」テーブルから選択するようにビューから選択します-すべての「非静的」フィルタリングはビューの外部で実行する必要があります(「Millerと呼ばれる顧客のすべての注文を取得する」または「未処理の注文を取得する」 12月24日に入った」)。

13

ストアドプロシージャや関数を使用せずにハックする方法は、列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
8
Bozonik

通常、ビューはパラメーター化されていません。ただし、常にいくつかのパラメーターを注入できます。たとえば、 セッションコンテキスト を使用する場合:

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;

DBFiddle Demo

同じことがOracleにも当てはまります(もちろん、コンテキスト関数の構文は異なります)。

8
Lukasz Szozda

ビューにパラメーターが必要なのはなぜですか? WHERE句を使用するだけです。

create view v_emp as select * from emp ;

そして、あなたのクエリは仕事をする必要があります:

select * from v_emp where emp_id=&eno;
7
Mahesh

いやその後、パラメータを渡すことができるユーザー定義関数を使用する必要がある場合。

6
Mladen Prajdic

入力パラメーターを使用してストアドプロシージャを作成し、そのストアドプロシージャを使用してビューから結果セットを取得できます。以下の例を参照してください。

ストアドプロシージャは

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%')  
5
sunil

私が知っているように、ビューはselectコマンドのようなものです。たとえば、次のようなwhereステートメントで、このselectにパラメーターを追加することもできます。

 WHERE  (exam_id = @var)
5
Reza Ameri

ビューは、事前に定義された「SELECT」ステートメントにすぎません。したがって、唯一の本当の答えは次のとおりです。いいえ、できません。

本当にしたいのは、ストアドプロシージャを作成することだと思います。原則として、有効なSQLを使用して、パラメータの受け入れやデータの選択など、必要な処理を実行できます。

ただし、ビューから選択するときにwhere句を追加するだけで十分な場合もありますが、確かに十分な詳細を提供していません。

5
Kris

いいえ、ビューは静的です。 (SQlサーバーのバージョンに応じて)できることの1つは、ビューにインデックスを付けることです。

あなたの例(1つのテーブルのみをクエリする)では、インデックス付きビューはインデックスを持つテーブルを単純にクエリする利点はありませんが、結合条件を持つテーブルで多くの結合を行う場合、インデックス付きビューはパフォーマンスを大幅に改善できます。

4
John

いいえ、ビューはテーブルからのSELECTと同様にクエリされます。

必要なことを行うには、1つ以上のパラメーターで テーブル値のユーザー定義関数 を使用します

4
MartW

関数を使用したくない場合は、次のようなものを使用できます

-- 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
        )

それが役立つことを願っています

3
Adnan Badar

いいえ、ビュー内のプロシージャにパラメータを渡すことができます

3
aicuxiao

これまで見たことのないオプションを次に示します。

ビューに制限する列を追加するだけです。

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)
2
FarajDaoud

ビューを実行するためだけにバイパスすることができます。SQLは失敗しますが、これを実行するだけで実行できます。保存できません。

create or replace view v_emp(eno number) as select * from emp where (emp_id = @Parameter1);
1
Kentonbmax

ビューは、パラメータを含む外部テーブルを参照できます。

他の人が述べたように、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
1
Oleg Melnikov

私はまだ試したことがないという考えを持っています。できるよ:

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)

パラメーターが保存され、構成テーブルで変更されます。

0
Emman