简体   繁体   中英

Passing arguments to views in SQL Server

Suppose I have a view that rolls up data via a GROUP BY clause:

CREATE VIEW InvoiceAmountsByCustomer AS
  SELECT
    Customer.CustomerID,
    SUM(Invoice.TotalAmount) AS TotalInvoiceAmount
  FROM
    Customer LEFT OUTER JOIN Invoice ON Customer.CustomerID = Invoice.CustomerID
  GROUP BY Customer.CustomerID

Now, suppose I want the view to restrict which invoices are included in the total based on a date range. To illustrate (pretending {From Date} and {To Date} contain the date range):

CREATE VIEW InvoiceAmountsByCustomer AS
  SELECT
    Customer.CustomerID,
    SUM(Invoice.TotalAmount) AS TotalInvoiceAmount
  FROM
    Customer LEFT OUTER JOIN Invoice ON Customer.CustomerID = Invoice.CustomerID
  WHERE
    Invoice.Date BETWEEN {From Date} AND {To Date}
  GROUP BY Customer.CustomerID

What do I replace {From Date} and {To Date} with so that I can pass their values (directly or indirectly) to the view? For example, is it possible to associate these values with the current session?

CREATE VIEW InvoiceAmountsByCustomer AS
  SELECT
    Customer.CustomerID,
    SUM(Invoice.TotalAmount) AS TotalInvoiceAmount
  FROM
    Customer LEFT OUTER JOIN Invoice ON Customer.CustomerID = Invoice.CustomerID
  WHERE
    Invoice.Date BETWEEN GetUserDefinedSessionValue('From Date') AND GetUserDefinedSessionValue('To Date')
  GROUP BY Customer.CustomerID

where GetUserDefinedSessionValue is an imaginary function that returns values associated with the current session. Another imaginary function, SetUserDefinedSessionValue would be called by the client prior to querying the view:

SetUserDefinedSessionValue('From Date', ...)
SetUserDefinedSessionValue('To Date', ...)
SELECT * FROM InvoiceAmountsByCustomer

My imaginary example is only meant to illustrate one way I envision these values being passed to the view.

Note: This is a trivial example and the real situation is much more complex, preventing me from executing a GROUP BY query directly by the client.

It is possible to call User Defined Functions within a view, yes, but I would rather use a User Defined Table Function , where you pass in the parameters you require, and this in turn returns the data you wish for.

User Defined Functions

An old thread, but I was browsing for an answer to this particular dilema my self, when it suddenly struck me that maybe the simplest way is the best.

Soulution 1: Skip the view entirely and write the complete sql in your code. Then you can declare parameteres as you'd like. Unless you are using indexed views there is not much difference between select * from 'view' and the entire select statement with the declare options.

Solution 2: Instead of using view, why not just create a procedure? This is less flexible, but if you plan on using select * from ' view ' It'll do the same thing.

Example:

CREATE proc dbo.ViewDates @from_date datetime, @to_date datetime AS 
SELECT
    Customer.CustomerID,
    SUM(Invoice.TotalAmount) AS TotalInvoiceAmount   FROM
    Customer LEFT OUTER JOIN Invoice ON Customer.CustomerID = Invoice.CustomerID   
WHERE
        Invoice.Date BETWEEN @from_date AND @to_date   GROUP BY Customer.CustomerID

Then, instead of select * :

exec dbo.ViewDates @from_date = '20120101', @to_date = '20120930'

You may need to format the dates by using @from_date = convert(datetime,'desired datestring', desired date format)

Ie

exec dbo.ViewDates @from_date = convert(datetime, '20120101',112), @to_date = convert(datetime,'20120930',112)

Here is one solution:

CREATE TABLE dbo.ViewDates (theDate DATETIME)

To query the database:

TRUNCATE TABLE viewDates

INSERT INTO viewDates VALUES (@fromDate)
INSERT INTO viewDates VALUES (@toDate)

To tweak the view

JOIN (select min(thedate) as StDate,max(theDate) as EnDate ) dt 
  ON invoice.date BETWEEN dt.StDate and dt.EndDate

Note that this will only work for one user at a time, if you need multiple users, you will need to add a user-id to the table, populate it, and adjust the query a bit...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM