【问题标题】:SQL, 'CREATE VIEW' must be the first statement in a query batchSQL, 'CREATE VIEW' 必须是查询批处理中的第一条语句
【发布时间】:2018-03-05 12:06:31
【问题描述】:

我得到以下错误:

'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 个日期变量并返回一个包含我将在 2 个不同位置使用的信息的表。

标签: sql sql-server-2008 variables declare create-view


【解决方案1】:

您不能将变量放在视图中。相反,使用内联表函数:

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

【讨论】:

  • 当我调用函数时,我可以使用变量而不是实际日期吗?
  • @Vic.D 。 . .您可以将所需的日期作为文字或变量传递。
【解决方案2】:

如前所述,您不能将变量放在视图中。你有两个选择。一种是创建一个返回表的函数(根据@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 语句绝对是查询批处理中的第一条语句,从而避免错误。您只需要确保查询中的所有引号都被适当地转义。

【讨论】:

  • 我不介意不使用视图。我需要创建一个小表并使用两次结果:提取 SKU 以供进一步使用,第二次计算循环获得了多少结果。我尝试创建 CTE,但由于某种原因,我无法调用两次使用它。我不想创建一个表,因此我决定创建一个视图来克服这个障碍,显然我不能在里面使用变量。任何其他可行的解决方案对我来说都很好。我不想创建视图并稍后过滤它,我不确定该功能是否是我的最佳解决方案。我还有哪些其他选择?
  • 如果您不需要将此作为长期解决方案,那么我对效率/重用的评论是没有意义的。我建议使用@GordonLinoff 提出的解决方案,或者如果您使用 CTE 方法,则只需复制 CTE 代码。您不能(据我所知)将一个 CTE 用于两个单独的查询。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多