【问题标题】:SQL Server 2012 using temp table of stored procedureSQL Server 2012 使用存储过程的临时表
【发布时间】:2015-11-20 23:22:30
【问题描述】:

首先感谢您的阅读。我遇到了无法解决的情况。

我创建了一个存储过程,它创建了一个包含两个日期之间天数的临时表。

示例:如果我将'2015-07-20''2015-07-25' 作为参数传递给存储过程,它将创建一个从2015 年7 月20 日到25 日有5 天的表。

我需要做的是在连接情况下使用这个临时表,比如这个查询。

 SELECT * 
 FROM control
 INNER JOIN
     (my table returned from sp  => exec calendario_dias ... ) ON dia = cta_dia

这是存储过程代码:

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[calendario_dias]
        (@fecha_ini date,
        @fecha_fin date)
AS
BEGIN
    IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID('#dias_calendar') AND type in (N'U'))
       DROP TABLE [dbo].#dias_calendar

    CREATE TABLE #dias_calendar(dia date)   

    WHILE @fecha_ini <= @fecha_fin
    BEGIN
        INSERT INTO #dias_calendar (dia) 
           SELECT @fecha_ini

        SET @fecha_ini = CONVERT(date, dateadd(day, 1, @fecha_ini))
    END 

    SELECT dia 
    FROM #dias_calendar
END

【问题讨论】:

标签: sql sql-server function stored-procedures inner-join


【解决方案1】:

这是一种带有 Tally-Table 功能的方法(您可以在任何地方使用它...)

编辑:现在使用自己的功能。您可以在任何地方使用和加入此功能...

CREATE FUNCTION [dbo].[GetRunningNumbers](@anzahl INT=10000000, @StartAt INT=0)
RETURNS TABLE
AS 
RETURN
WITH E1(N) AS( -- 10 ^ 1 = 10 rows
    SELECT 1 FROM(VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))t(N)
),
E2(N) AS(SELECT 1 FROM E1 a CROSS JOIN E1 b), -- 10 ^ 2 = 100 rows
E4(N) AS(SELECT 1 FROM E2 a CROSS JOIN E2 b), -- 10 ^ 4 = 10,000 rows
E8(N) AS(SELECT 1 FROM E4 a CROSS JOIN E4 b), -- 10 ^ 8 = 10,000,000 rows
CteTally AS(
    SELECT TOP(ISNULL(@anzahl,1000000)) ROW_NUMBER() OVER(ORDER BY(SELECT NULL)) -1 + ISNULL(@StartAt,0) As Nmbr
    FROM E8
)
SELECT * FROM CteTally;
GO

CREATE FUNCTION dbo.DateLine
(
     @d1 DATETIME
    ,@d2 DATETIME
)
RETURNS TABLE
AS
RETURN
SELECT DATEADD(DAY,runningNumbers.Nmbr,@d1) AS DateRunning
FROM dbo.GetRunningNumbers(ABS(DATEDIFF(DAY,@d1,@d2))+1,0) AS runningNumbers

GO

--Always three dates with one obejct...
SELECT  name,object_id,DateRunning
FROM sys.objects 
CROSS APPLY dbo.DateLine({ts'2015-07-01 00:00:00'},{ts'2015-07-03 00:00:00'}) AS dl
ORDER BY object_id,DateRunning
GO

DROP FUNCTION dbo.DateLine;
DROP FUNCTION dbo.GetRunningNumbers;
GO

【讨论】:

    【解决方案2】:

    Temporary Tables 在您的连接中是本地的,并且在不再使用时会被删除。它们的工作方式和行为类似于常规表。

    试试:

    CREATE TABLE test1(
        [Id] [bigint] IDENTITY(1,1) NOT NULL,
        [Column1] [int] NULL,
        [Column2] [int] NULL
    ) ON [PRIMARY]
    
    
    insert into test1(column1,column2) values(1,2),(3,4),(5,6),(7,8)
    

    以及加入:

    create table #tbl1(Id bigint Identity,value1 varchar(max))
    
    insert into #tbl1(value1) values('a'),('b'),('c'),('d')
    
    select * from test1 join #tbl1 on test1.Id=#tbl1.Id
    

    fiddle demo

    【讨论】:

      【解决方案3】:

      明确回答

      SET ANSI_NULLS ON
      GO
      SET QUOTED_IDENTIFIER ON
      GO
      CREATE FUNCTION calendario_dias
      (
      -- Add the parameters for the function here
      @fecha_ini date, 
      @fecha_fin date
      
      )
      RETURNS
      @dias_calendar TABLE
      (
      -- Add the column definitions for the TABLE variable here
      dia date
      )
      AS
      BEGIN
      -- Fill the table variable with the rows for your result set
      
      WHILE @fecha_ini <= @fecha_fin
      BEGIN
      INSERT INTO @dias_calendar
      SELECT @fecha_ini
      SET @fecha_ini = CONVERT(date, dateadd(day, 1, @fecha_ini))
      END
      
      RETURN
      END
      GO
      

      然后:

      SELECT *
      FROM control
      INNER JOIN
      [dbo].[calendario_dias](@fecha_ini date,@fecha_fin date)
      ON dia = cta_dia
      

      【讨论】:

      • 不是你建议的inline函数吗?内联函数是单语句调用,没有 WHILE 和其他过程代码...只是纯粹的、基于集合的 SQL...
      • 你是新来的,只是一个提示:如果你已经给出了答案,最好编辑这个而不是开始一个新的......
      • @Shnugo 很抱歉,我第一眼就没有看到他的 TSQL,因此我发布了一个新答案
      • 除非必要,否则请不要使用 WHILE 循环。这可以通过内联 TVF 轻松实现,无需循环(如 @Shnugo 所示)。内联 TVF 效率更高。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-26
      • 2011-03-21
      • 2021-01-05
      • 1970-01-01
      • 1970-01-01
      • 2019-01-06
      • 1970-01-01
      相关资源
      最近更新 更多