如何防止 SQL 服务器自动将有效语法重新排列为无效语法?

How to prevent SQL server from automatically rearranging valid syntax into an invalid?

我注意到每次我想更新视图 sql 语法时,我都会收到一个错误,尤其是 CTE。

WITH
Settings (DateMin, DateMax, DateDiffer)
AS
(
    select dateadd(year, -5, getDate()), dateadd(year, 5, getDate()), 
    datediff(day, dateadd(year, -5, getDate()), dateadd(year, 5, getDate()))
),
Tally (N) AS
(
    SELECT dateadd(day, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)), (select top 1 DateMin from Settings))
    FROM sys.all_columns
     a CROSS JOIN sys.all_columns b
)

select top (select top 1 datediffer from Settings) N as Date
from Tally

原来是

SELECT        dateadd(year, - 5, getDate()), dateadd(year, 5, getDate()), datediff(day, dateadd(year, - 5, getDate()), dateadd(year, 5, getDate()))), Tally(N) AS
    (SELECT        dateadd(day, ROW_NUMBER() OVER (ORDER BY 
                                    (SELECT        NULL)),
    (SELECT        TOP 1 DateMin
      FROM            Settings))
FROM            sys.all_columns a CROSS JOIN
                         sys.all_columns b)
    SELECT        TOP
                                  (SELECT        TOP 1 datediffer
                                    FROM            Settings) N AS Date
     FROM            Tally

有没有办法防止这种情况发生

如果您使用 sql 而不是视图设计器,它不会更改您的任何代码。

go
create view dbo.myview as 
with settings (datemin, datemax, datediffer) as (
    select 
        datemin=convert(date,dateadd(year, -5, getdate()))
      , datemax=convert(date,dateadd(year, 5, getdate()))
      , datediffer=1+datediff(
          day
          , dateadd(year, -5, getdate())
          , dateadd(year, 5, getdate())
          )
)
, tally (N) as ( 
  select 
    N =dateadd(
        day
        , row_number() over (order by (select 1))  - 1
        ,  (select top 1 datemin from settings)
        )
    from sys.all_columns
     a cross join sys.all_columns b
)

select top (select top 1 datediffer from settings) 
  date = N 
from tally
go
select top 1 * from dbo.myview order by date

注意:如果你想让它从5年前的今天开始,那么你需要将行号减一。

rextester:http://rextester.com/ADOG58877

为此使用视图的替代方法是创建日历 table。

if object_id('dbo.Calendar') is not null drop table dbo.Calendar;
create table dbo.Calendar (
    [Date]         date     not null
  , constraint pk_Calendar primary key clustered (date)
  );

declare @FromDate date = '20100101';
declare @ThruDate date = '20301231';

with n as (select n from (values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) t(n))
, d as (
  select DateValue=convert(date,dateadd(day
      , row_number() over (order by (select 1)) -1, @fromdate))
    from         n as deka
      cross join n as hecto
      cross join n as kilo     /* 2.73 years */
      cross join n as [tenK]    /* 27.3 years */
      --cross join n as [hundredk] /* 273  years */
      --cross join n as mega
)
insert into dbo.Calendar 
    ([Date], [Year], [Month], [Quarter], [YearMonth],[YearQuarter])
  select top (datediff(day, @FromDate, @ThruDate)+1) 
      [Date]        = DateValue
    from d
    order by DateValue;