SQL, CREATE VIEW должен быть первым оператором в пакете запроса

Я получаю следующую ошибку:

"CREATE VIEW" должен быть первым оператором в пакете запроса.

Я пытаюсь создать представление и вставить параметры даты в качестве переменной в запросе. По какой-то причине это не работает, есть идеи, как это преодолеть? Вот запрос

 DECLARE **@StartDate** date='2017-05-29 00:00:00';

GO 
 DECLARE **@EndDate** date='2018-03-04 00:00:00';

GO

 CREATE  VIEW [FG_Cargo] AS

 SELECT c.ContainerName,P.Description,
 WFS.WorkflowStepName,WFB.WorkflowName,  HML.TxnDate, hml.CDOTypeId,
 hml.TxnType

 FROM Container C join HistoryCrossRef HCR on
 (c.ContainerId=HCR.TrackingId) JOIN HistoryMainline HML
 ON(HCR.HistoryId=HML.HistoryId) JOIN Product P ON
 (C.ProductId=P.ProductId) JOIN WorkflowStep WFS ON
 (HML.WorkflowStepId=WFS.WorkflowStepId) JOIN Workflow WF ON
 (WFS.WorkflowId=WF.WorkflowId) JOIN WorkflowBase WFB ON
 (WF.WorkflowBaseId=wfb.WorkflowBaseId)

 WHERE C.ContainerName LIKE('KT%') AND WFS.WorkflowStepName='release
 for shipping' AND  TxnType='6640' AND HML.TxnDate BETWEEN
 **@StartDate** AND **@EndDate** ;

 GO

 SELECT* FROM FG_Cargo

2 ответа

Вы не можете поместить переменные в представление. Вместо этого используйте встроенную табличную функцию:

CREATE FUNCTION dbo.ufn_fg_cargo (
    @StartDate date,
    @EndDate date
) RETURNS table
AS
RETURN (SELECT c.ContainerName, P.Description, WFS.WorkflowStepName, 
               WFB.WorkflowName, HML.TxnDate, hml.CDOTypeId, hml.TxnType
        FROM Container C JOIN
             HistoryCrossRef HCR 
             ON c.ContainerId = HCR.TrackingId JOIN
             HistoryMainline HML
             ON HCR.HistoryId = HML.HistoryId JOIN
             Product P
             ON C.ProductId = P.ProductId JOIN
             WorkflowStep WFS
             ON HML.WorkflowStepId = WFS.WorkflowStepId JOIN
             Workflow WF
             ON WFS.WorkflowId = WF.WorkflowId JOIN
             WorkflowBase WFB
             ON WF.WorkflowBaseId = wfb.WorkflowBaseId
        WHERE C.ContainerName LIKE 'KT%' AND 
              WFS.WorkflowStepName = 'release for shipping' AND 
              TxnType = '6640' AND
              HML.TxnDate BETWEEN @StartDate AND @EndDate 
       );

Затем вы можете использовать это как:

select c.*
from dbo.ufn_fg_cargo('2017-05-29', '2018-03-04') c

Как уже было сказано, вы не можете поместить переменные в представление. У вас есть два варианта. Одним из них является создание функции, которая возвращает таблицу (согласно ответу, предоставленному @GordonLinoff). Другой вариант, который во многом зависит от объема данных, представляемых представлением, состоит в том, чтобы создать представление со всеми датами, а затем выполнить фильтрацию позже.

Я должен был бы подтвердить это, но я предполагаю, что использование функции приведет к перестроению таблицы каждый раз, когда вы обращаетесь к функции, тогда как представление создается / перестраивается только при изменении базовых таблиц / данных?

РЕДАКТИРОВАТЬ

Чтобы избавиться от ошибки и предположить, что вам нужен просмотр, вы можете сделать следующее:

IF NOT EXISTS (
    SELECT * FROM INFORMATION_SCHEMA.VIEWS  
    WHERE TABLE_SCHEMA = 'dbo' 
        AND TABLE_NAME = 'FG_Cargo'
)
BEGIN
    EXECUTE('
        CREATE VIEW [dbo].[FG_Cargo]
        AS
            SELECT 
        ...
    ')
END;
GO

Это гарантирует, что CREATE VIEW оператор безусловно является первым оператором в пакете запросов, и вы избежите ошибки. Вам просто нужно убедиться, что любые кавычки в вашем запросе должным образом экранированы.

Другие вопросы по тегам