【问题标题】:SQL Create view with declare in SQL serverSQL 在 SQL Server 中使用声明创建视图
【发布时间】:2021-11-28 12:07:30
【问题描述】:

在 SQL 查询中,我有多个声明变量,它工作正常,但我想将其转换为视图,但出现错误。下面是脚本,请帮助我将其转换为视图。非常感谢。我尝试过表值函数并在里面使用函数无法成功。

--create view TEST_VIEW AS 
DECLARE
@COL1 @COL2 @COL3 
@COL4 
@COL5 
@COL6 int,
@COL7 nvarchar(1000),
@COL8 int,
@COL9 nvarchar(100),
@COL10 nvarchar(100)
DECLARE 
@temp TABLE (  @COL1 @COL2 @COL3 
@COL4 
@COL5 ,
COL6 int,
COL7 nvarchar(1000),
COL8 int,
COL9 nvarchar(100),
COL10 nvarchar(100));
DECLARE cursor_Update CURSOR fast_forward
FOR select  @COL1 @COL2 @COL3 
@COL4 
@COL5 
,COL6
,COL7
,COL8
,COL9
,COL10 from G.FACT_G_DEPLOYMENTS;
OPEN cursor_Update;

FETCH NEXT FROM cursor_Update INTO   @COL1 @COL2 @COL3 
@COL4 
@COL5 @COL6,
@COL7,@COL8,@COL9,@COL10;

WHILE @@FETCH_STATUS = 0
BEGIN
Declare @TotalMonth int;
If (@COL10 is null)
Begin
set @TotalMonth = DATEDIFF(MONTH,convert(date,@COL4 ,103),GETDATE())
End
else
Begin

PRINT @COL10;
set @TotalMonth = DATEDIFF(MONTH,@COL4,CAST(@COL10 AS DATETIME))
End

DECLARE @Counter INT
SET @Counter=0;
WHILE ( @Counter <= @TotalMonth)
BEGIN

INSERT INTO @temp VALUES( @COL1,@COL2,@COL3,DATEADD(MONTH,@Counter, convert(date,@COL4 ,103)),@COL5,@COL6,
@COL7,@COL8,@COL9,@COL10)

SET @Counter = @Counter + 1;
END

FETCH NEXT FROM cursor_Update INTO @COL1,COL6,
@COL7,@COL8,@COL9,@COL10;
END;
CLOSE cursor_Update;
DEALLOCATE cursor_Update;
SELECT * FROM @temp;

【问题讨论】:

  • 你不想要一个视图你想要一个存储过程。 Fwiw 你的光标也完全没有必要。
  • 在一个简单的 SELECT 查询中重写这段代码,它会解决你的问题
  • VIEW 必须由 single SELECT 语句定义;仅此而已,仅此而已。没有DECLAREs,没有INSERTs,只有SELECT(包括CTE,因为那是一个表达式)也许,您想要一个内联表值函数。上面肯定有多个缺陷。例如,你有CURSOR,这几乎是总是错误的选择(一方面我可以数出你应该使用CURSOR 的次数)。
  • @Col2,@Col3,@Col4,@Col5 都没有声明,它们来自哪里?您需要一个计数表或计数功能,而不是光标。 @Stu没有理由不能成为一个观点。 @Col4 是日期还是 varchar?
  • 如果您希望其他人阅读您的代码,请正确缩进。从长远来看,它也会对您有所帮助。

标签: sql sql-server ssis


【解决方案1】:

游标速度慢且效率低,不能在视图中使用。

您可以通过使用tally/numbers table or function 来消除对光标的需求。我在这里使用了动态 CTE,但还有其他方法。

由于代码中的语法错误,不清楚某些列的来源,所以我在这里猜测了一下。

CREATE OR ALTER VIEW TEST_VIEW AS 

WITH L0 AS (
    SELECT 1 c 
    FROM (VALUES(1),(1),(1),(1),(1),(1),(1),(1),
                        (1),(1),(1),(1),(1),(1),(1),(1)) AS D(c)
),
L1 AS (
    SELECT 1 c             -- good for 4096 rows
    FROM L0 A, L0 B, L0 C  -- add more cross-joins for more rows
)
Nums AS ( SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS rownum
          FROM L1
)
SELECT
  COL1,
  COL2,
  COL3,
  v2.Month,
  COL5,
  COL6,
  COL7,
  COL8,
  COL9,
  COL10
FROM G.FACT_G_DEPLOYMENTS dep
CROSS APPLY (VALUES(
    DATEDIFF(MONTH, @COL4, ISNULL(CAST(COL10 AS DATETIME), GETDATE()))
)) v1(TotalMonth)
CROSS APPLY (
    SELECT TOP (v.TotalMonth)
      Month = DATEADD(MONTH, rn - 1, convert(date,@COL4 ,103))
    FROM Nums
) v2;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-06
    • 1970-01-01
    • 1970-01-01
    • 2012-02-15
    • 1970-01-01
    • 2011-12-09
    • 1970-01-01
    相关资源
    最近更新 更多