2009-11-06 15 views
76

È possibile passare un parametro a una vista in Microsoft SQL Server?Possiamo passare i parametri a una vista in SQL?

ho cercato di create view nel seguente modo, ma non funziona:

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

Una vista è un testo memorizzato SQL di una query di selezione. I parametri sono fuori discussione. Quando la query memorizzata restituisce la colonna in cui si desidera filtrare, è possibile farlo nella query di chiamata. Per esempio. "SELECT * FROM v_emp WHERE emp_id =?" – Epicurist

risposta

5

no. se è necessario quindi utilizzare una funzione definita dall'utente a cui è possibile passare i parametri.

11

No, non è possibile, come ha detto Mladen Prajdic. Pensa a una vista come "filtro statico" su una tabella o una combinazione di tabelle. Ad esempio: una vista può combinare le tabelle Order e Customer in modo da ottenere una nuova "tabella" di righe da Order insieme a nuove colonne contenenti il ​​nome del cliente e il numero cliente (combinazione di tabelle). Oppure puoi creare una vista che seleziona solo ordini non elaborati dalla tabella Order (filtro statico).

Dovresti quindi selezionare dalla vista come se dovessi scegliere da qualsiasi altra tabella "normale" - tutti i filtri "non statici" devono essere eseguiti all'esterno della visualizzazione (ad esempio "Ricevi tutti gli ordini per i clienti chiamati Miller" o "Ricevi ordini non elaborati arrivati ​​il ​​24 dicembre").

24

Ci sono 2 modi per acheive ciò che si desidera purtroppo non può essere fatto utilizzando la vista.

È possibile creare una funzione definita dall'utente con valori di tabella che prende il parametro che si desidera e restituisce un risultato della query

Oppure si può fare più o meno la stessa cosa, ma creare una stored procedure, invece di una funzione definita dall'utente.

Per esempio

la stored procedure sarà simile

CREATE PROCEDURE s_emp 
(
    @enoNumber INT 
) 
AS 
SELECT 
    * 
FROM 
    emp 
WHERE 
    [email protected] 

o la funzione definita dall'utente sarebbe simile

CREATE FUNCTION u_emp 
( 
    @enoNumber INT 
) 
RETURNS TABLE 
AS 
RETURN 
(
    SELECT  
     * 
    FROM  
     emp 
    WHERE  
     [email protected] 
) 
4

senza si può passare il parametro alla procedura in vista

94

Come già affermato non è possibile.

Una possibile soluzione potrebbe essere quella di implementare una funzione memorizzata, come:

CREATE FUNCTION v_emp (@pintEno INT) 
RETURNS TABLE 
AS 
RETURN 
    SELECT * FROM emp WHERE [email protected]; 

Questo consente di utilizzare come una vista normale, con:

SELECT * FROM v_emp(10) 
+0

Quali sono le differenze pratiche tra questo e una vista? È possibile assegnare autorizzazioni utente per accedere solo a questa funzione? – MikeMurko

+0

In MySQL si scrive una stored procedure e l'ultima istruzione nella procedura è il set di risultati che si desidera restituire. – bobobobo

+0

possiamo usare quella richiesta senza alcun problema dal codice JDBC in java? – mounaim

4

Un punto di vista non è altro che una dichiarazione "SELECT" predeterminata. Quindi l'unica vera risposta sarebbe: No, non puoi.

Penso che quello che si vuole veramente fare è creare una procedura memorizzata, in cui in linea di principio è possibile utilizzare qualsiasi SQL valido per fare tutto ciò che si desidera, compresi i parametri di accettazione e selezione dei dati.

Sembra probabile che tu abbia davvero bisogno di aggiungere una clausola where solo quando selezioni dalla tua vista, ma non hai fornito abbastanza dettagli per essere sicuro.

4

No, una vista è statica. Una cosa che puoi fare (a seconda della versione del server SQl) è indicizzare una vista.

Nell'esempio (l'esecuzione di una query su una sola tabella), una vista indicizzata non ha alcun vantaggio di interrogare semplicemente la tabella con un indice su di essa, ma se si stanno facendo molti join su tabelle con condizioni di join, una vista indicizzata può migliorare notevolmente le prestazioni.

4

possiamo scrivere una stored procedure con i parametri di input e quindi utilizzare quella stored procedure per ottenere un set di risultati dalla vista. vedi esempio sotto.

stored procedura è

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 [email protected] 
    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 [email protected] 
End 
Else 
Begin 
    Select * from vw_Report_LoginSuccess 
    where logindatetime between dbo.DateFloor(@fromDate) and dbo.DateSieling(@toDate) 
End 

End 

e la vista da cui si può ottenere il set di risultati

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

Un modo hacky per farlo senza stored procedure o funzioni sarebbe creare un tabella delle impostazioni nel tuo database, con le colonne Id, Param1, Param2, ecc. Inserisci una riga in quella tabella contenente i valori Id = 1, Param1 = 0, Param2 = 0, ecc. Quindi puoi aggiungere un join a quella tabella nel tuo visualizzare per creare l'effetto desiderato e aggiornare la tabella delle impostazioni prima di eseguire il vie w. Se si hanno più utenti che aggiornano la tabella delle impostazioni ed eseguono la vista contemporaneamente, le cose potrebbero andare storte, ma altrimenti dovrebbe funzionare correttamente. Qualcosa di simile:

CREATE VIEW v_emp 
AS 
SELECT  * 
FROM  emp E 
INNER JOIN settings S 
ON   S.Id = 1 AND E.emp_id = S.Param1 
+7

Sì, hai ragione. Questa è una soluzione orribile. – Ben

+0

sarebbe terribile usarlo per una richiesta di visualizzazione. Ma è davvero utilizzabile, come configurazione/stage/ambiente, utilizzare tali parametri nascosti. Un plus per me per quello. – TPAKTOPA

3

Come so, la vista può essere qualcosa come il comando di selezione. È inoltre possibile aggiungere parametri per questo selezionare per esempio in cui affermazioni come questa:

WHERE (exam_id = @var) 
+0

Questa dovrebbe essere accettata risposta. Semplice, facile e fino al punto. Grazie mille :) – FrenkyB

5

Perché avete bisogno di un parametro in vista? Potresti semplicemente usare la clausola WHERE.

create view v_emp as select * from emp ; 

e la query dovrebbe fare il lavoro:

select * from v_emp where emp_id=&eno; 
+3

In alcuni casi ci sarà un grande miglioramento delle prestazioni, quando è un 'WHERE' per la tabella, invece di un' WHERE' per la vista. –

3

Se non si desidera utilizzare una funzione, è possibile utilizzare qualcosa di simile

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

auguriamo che contribuiscano

1

È possibile ignorare solo per eseguire la vista, SQL sarà vino e piangere ma basta farlo ed eseguirlo! Non puoi salvare.

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

Qui è un'opzione che non ho visto finora:

Basta aggiungere la colonna che si desidera limitare a vista:

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

tuo punto di vista può fare riferimento a qualche tavolo esterno contenente i tuoi parametri

Come già menzionato, la vista in SQL Server non può avere parametri di input esterni.Tuttavia, puoi facilmente falsificare una variabile nella tua vista usando CTE. Puoi test-eseguirlo nella tua versione di 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 

uscita cedevole:

status name 
12  dbo 
0  db_accessadmin 
0  db_securityadmin 
0  db_ddladmin 

anche tramite 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 

anche tramite 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 
Problemi correlati