我需要将一些存储过程转换为视图,并且存储过程有很多DECLARE
语句,这些语句创建了稍后在查询中引用的常量。例如
SELECT @FIRSTDAYLASTYEAR = DATEADD(YEAR, DATEDIFF(YEAR, '1901-01-01', DATEADD(YEAR, -1, getdate())), '1901-01-01')
我需要多次在单个查询中引用@FIRSTDAYLASTYEAR
,在不必声明变量的情况下,最好的方法是什么?
例如考虑:
DECLARE @FIRSTDAYLASTYEAR datetime = DATEADD(YEAR, DATEDIFF(YEAR, '1901-01-01', DATEADD(YEAR, -1, getdate())), '1901-01-01')
select
@FIRSTDAYLASTYEAR as FirstDayLastYear,
Case when orderDate > @FIRSTDAYLASTYEAR then 'CurrentOrders' else 'ArchiveOrders' end as State
from
orders
我不想重写为
select
DATEADD(YEAR, DATEDIFF(YEAR, '1901-01-01', DATEADD(YEAR, -1, getdate())), '1901-01-01') as FirstDayLastYear,
Case when orderDate > DATEADD(YEAR, DATEDIFF(YEAR, '1901-01-01', DATEADD(YEAR, -1, getdate())), '1901-01-01') then 'CurrentOrders' else 'ArchiveOrders' end as State
from
orders
我希望能够在查询中以某种方式对@FIRSTDAYLASTYEAR
进行别名。
修改
感谢您的回复,您认为这会有相同的表现吗?
select
constants.FirstDayLastYear,
Case when orderDate > constants.FirstDayLastYear then 'CurrentOrders' else 'ArchiveOrders' end as State
from
orders o
cross join
(select
DATEADD(YEAR, DATEDIFF(YEAR, '1901-01-01', DATEADD(YEAR, -1, getdate())), '1901-01-01') as FirstDayLastYear
) as constants
我要问的原因是,此代码可能会在未来支持CTE的日期移植到另一个数据库平台。
答案 0 :(得分:2)
您可以构造一个包含所有变量的单行的CTE,然后在查询中引用它:
WITH Consts as (
SELECT DATEADD(YEAR, DATEDIFF(YEAR, '19010101', getdate()), '19000101')
as FirstDayLastYear,
DATEADD(YEAR, DATEDIFF(YEAR, '19010101', getdate()), '19001231')
as LastDayLastYear
)
select
c.FirstDayLastYear,
Case when orderDate > c.FirstDayLastYear then 'CurrentOrders' else 'ArchiveOrders' end as State
from
orders
cross join
Consts c
如果您有基于其他变量构建的变量,则可能需要具有多个级别的CTE。
答案 1 :(得分:1)
您还可以使用APPLY VALUES
:
SELECT
FirstDateLastYear as FirstDayLastYear,
CASE WHEN orderDate > FirstDateLastYear THEN 'CurrentOrders' ELSE 'ArchiveOrders' END AS State
FROM orders
CROSS APPLY (VALUES(DATEADD(YEAR, DATEDIFF(YEAR, '1901-01-01', DATEADD(YEAR, -1, getdate())), '1901-01-01'))) AS date(FirstDateLastYear);
答案 2 :(得分:0)
您应该考虑像
这样的'常用表格式'WITH vars AS (
SELECT DATEADD(YEAR, DATEDIFF(YEAR, '1901-01-01', DATEADD(YEAR, -1, getdate())), '1901-01-01') as FirstDayLastYear)
)
SELECT Case when orderDate > FirstDayLastYear) then 'CurrentOrders' else 'ArchiveOrders' end as State
... --- your actual select statement for the view ...
FROM orders, vars
...
答案 3 :(得分:0)
SQL Server中的视图中不允许使用局部变量 在您描述的情况下,我可能会创建一个视图来封装存储过程中使用的变量的值,然后在更大的视图中查询该视图作为子查询或派生表(根据您的需要)。
但是,这可能无法转换存储过程中的所有局部变量。对于不可能的情况,您可以创建一个用户定义的函数来封装局部变量的值,并以我使用该视图描述的相同方式使用它。
您可以创建cte
而不是视图,但是如果您需要相同的逻辑来应用于多个视图,则必须为转换为的每个过程编写cte
图。
答案 4 :(得分:0)
您可以创建标量函数:
CREATE FUNCTION fnPrevYear ( )
RETURNS date
AS
BEGIN
RETURN DATEADD(YEAR, DATEDIFF(YEAR, '1901-01-01', DATEADD(YEAR, -1, GETDATE())), '1901-01-01')
END
并在需要时调用它:
SELECT dbo.fnPrevYear()
但是大数据会很慢。您可以使用公用表表达式作为更好的替代方法。