简体   繁体   中英

Execute a Stored Procedure Inside a View?

I started working for a company a few weeks ago, and have inherited a crazy mess of databases. I'm currently working on designing the new systems to replace their older ones. The previous developer created a ton of views that are entirely identical, with the only differences being the conditions within the WHERE clause. In my attempt to cleanup the source, I was attempting to create a stored procedure that returns the table based on the given conditions, so I can compact 250 views into a single stored procedure.

Honestly, the only reason I'm doing this is so when I start transitioning over to the newer databases and front-ends, I have some pre-made stored procedures to use rather than a jumbled mess of views.

Is there any way that I can execute the stored procedures I created inside of the currently existing views, so I don't have to modify their front end (A series of access databases connected to SQL Server through ODBC)?

My stored procedure looks something like this:

CREATE PROCEDURE BusDuctQueries.CMSF_Current_Mod @ModNumber VARCHAR(255)
AS
   SELECT        [Date], [Name], [Mod], [Cell], [Row], [Section],
    [Phase A Breaker Amps], [Phase B Breaker Amps], [Phase C Breaker Amps], 
    [Phase A Actual Amps], [Phase B Actual Amps], [Phase C Actual Amps], 
    [PDU # 1], [Bus Duct # 1], 
    [Bus Duct # 1 Phase A Current Load], [Bus Duct # 1 Phase B Current Load], [Bus Duct # 1 Phase C Current Load], 
    [PDU # 2], [Bus Duct # 2], 
    [Bus Duct # 2 Phase A Current Load], [Bus Duct # 2 Phase B Current Load], [Bus Duct # 2 Phase C Current Load], 
    [Sort 1], [Sort 2], [Average Load], [Percent Used], [Percent Remaining], [KW Used], 
    CONVERT(NUMERIC(18, 2), [Derated KW Left]) AS [Derated KW Left], 
    CONVERT(NUMERIC(18, 2), [True KW Left]) AS [True KW Left], 
    CASE WHEN [PDU # 1] LIKE '%A%' THEN 1 ELSE 2 END AS UPSSort
FROM            BusDuctQueries.[CMSF Current]
WHERE        ([Mod] = @ModNumber) AND  (Cell NOT LIKE '%WP%')

You cannot call a stored proc from inside a view. It is not supported. However you can make views call other views, or table-valued user-defined functions .

For the latter you must make sure that you're using inline functions . Otherwise, any subsequent clauses like WHERE , GROUP BY and ORDER BY to be performed on the dynamically produced resultset instead. Thus, you won't benefit from index searches and the likes. This may have a huge impact on performance.

There are two ways to do this, both with their pros and cons:

  1. Use OPENROWSET / OPENQUERY . These allow you do do a SELECT on anything you want, but it might have security implications that you don't like. That might not be an issue if this is a short-term solution and afterwards you can undo the allowing of "Ad Hoc Distributed Queries". But this is the easiest to set up, especially if the result sets vary between the procs (assuming that there are multiple procs).

  2. Write a SQLCLR TVF that executes the procedure. This can be done in SAFE mode if the Stored Procedures are read-only (ie no INSERT / UPDATE / DELETE statements and most likely no CREATE #Tmp statements). I wrote an article showing an example of this: Stairway to SQLCLR Level 2: Sample Stored Procedure and Function

If you want to do some heavy lifting, perhaps manipulating table variables, using while loops and so on, then use a function and reference that from your view.

You can't use a stored procedure because stored procs are allowed to edit your data - as such if you could reference them from a view, then a select could have side effects - which is not allowed.

You can easily convert procedures like this into inline TVFs, also known as parameterized views. The body of the view will remain identical to what you have in the procedure.

Selecting from views/TVFs is different than executing stored procedures, so you might have to change the front end anyway. In any case, someone will have to supply values for the parameters.

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