Кажется, я не могу получить правильный синтаксис для вызова хранимой процедуры в инструкции Select

#sql-server #tsql #stored-procedures

#sql-server #tsql #хранимые процедуры

Вопрос:

У меня есть простая хранимая процедура, выходные данные которой я хочу использовать в формуле.

Моя хранимая процедура выглядит следующим образом:

 USE [MGCustom]
GO
/****** Object:  StoredProcedure [dbo].[stpGetCogAmt]    Script Date: 4/10/2019 4:55:17 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      Mike Ruoppoli
-- Create date: 
-- Description: <Procedure to get the Cogs value based on the month,Values to be included in a table later.>
-- =============================================
ALTER PROCEDURE [dbo].[stpGetCogAmt]
    -- Add the parameters for the stored procedure here
    @ProdMonth int
,   @CogsRate DECIMAL(4,4)  OUTPUT
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here

    --@CogsPerLb, @p2
    Set @CogsRate =(CASE @ProdMonth 
            WHEN 1 THEN 0.0957 WHEN 2 THEN 0.0904 WHEN 3 THEN 0.0884 WHEN 4 THEN 0.0906 WHEN 5 THEN 0.0818 WHEN 6 THEN 0.0787 WHEN 7 THEN 0.0777 WHEN 8 THEN 0.0769 WHEN 9 THEN 0.0756 WHEN 10 THEN 0.0778
            WHEN 11 THEN 0.0754 WHEN 12 THEN 0.0787 ELSE .08 END) 

END
  

Хранимая процедура выполняется и возвращает значение, как ожидалось, но когда я пытаюсь использовать в этом контексте, я продолжаю получать неправильный синтаксис рядом с ‘EXEC’

Больше кода

 SELECT dbo.vwUD15.Date01, (EXEC dbo.stpGetCogAmt @ProdMonth = "(LEFT(dbo.vwUD15.Key2, LEN(dbo.vwUD15.Key2) - 5))") AS CogsRate
FROM dbo.vwUD15
  

Я много искал и не могу понять, что я здесь делаю не так.

Я буду использовать этот sproc во многих формулах…

Комментарии:

1. Когда я говорю, что выполняется sproc, я имею в виду, когда я использую обозреватель объектов «Выполнить хранимую процедуру», где вы можете вручную установить входной параметр.

2. Я предполагаю, что это SQL Server? Если это так, ответ — вы этого не делаете. Хранимые процедуры не могут быть частью более крупного запроса.

3. Вы не можете вызвать хранимую процедуру как часть запроса SELECT. Вам нужно преобразовать это в функцию, если вы хотите это сделать

Ответ №1:

Один из комментариев в коде указывает на гораздо лучший способ моделирования этого:

 create table CogRates (
    ProdMonth int not null,
    CogsRate decimal(4,4) not null,
    constraint PK_CogRates PRIMARY KEY (ProdMonth),
    constraint CK_CogRates_Months CHECK (ProdMonth between 1 and 12)
)
go
insert into CogRates (ProdMonth,CogsRate) values
(1 ,0.0957),
(2 ,0.0904),
(3 ,0.0884),
(4 ,0.0906),
(5 ,0.0818),
(6 ,0.0787),
(7 ,0.0777),
(8 ,0.0769),
(9 ,0.0756),
(10,0.0778),
(11,0.0754),
(12,0.0787)
go
SELECT v.Date01, cg.CogsRate AS CogsRate
FROM dbo.vwUD15 v
    inner join
    CogRates cg
        on cg.ProdMonth = LEFT(v.Key2, LEN(v.Key2) - 5)
  

Не пишите процедурный код, когда код на основе набора будет выполнять эту работу.

Хранимые процедуры не могут быть объединены в более крупные запросы. Вы могли бы перенести свою логику в определяемую пользователем функцию, но когда это в основном поиск, это то, в чем SQL превосходит. (Хотя было бы предпочтительнее, если бы мы не выполняли манипуляции со значением столбца в правой части этого сравнения)

В общем, если вы планируете написать функцию (а не хранимую процедуру), и определение является детерминированным, а домен «маленьким», рассмотрите возможность использования таблицы вместо этого. В качестве бонуса вы также получаете обратную функцию бесплатно, если вам это нужно.

Комментарии:

1. И было бы намного лучше материализовать — каким-то образом — значение из представления, используемого для объединения.