2017-05-05 72 views
1

目标:创建一个存储过程来自动执行此报告,以便当运行execute NameOfStoredProc时,它会执行所有3个块并返回块3中的查询SQL Server T-SQL:使用存储过程自动重新执行SQL报告

对于表格,我希望它是基于getdate()的动态。

(我没有张贴实际的表元素和记录,但如果需要,我可以弥补一些B/C的实际数据是敏感的)

  • 数据库:FY1516
  • 从表:v_all_claim(实际上是视图)进入表
  • March2017_Payments

下面是我手工执行生成报告的代码。

块1:

--creates payment table 
SELECT Recipient_ID, DOP, Provider_ID, program_code, poverty_code 
INTO FY1516..March2017_Payments 
FROM FY1516..v_all_Claim 
WHERE amount <> 0 
    AND DOP BETWEEN '20170301' AND '20170331' 

2座:

-- add one column to the table created in block 1, sets default value to '' and update to Y 
-- if certain constraints are met 
ALTER TABLE FY1516..March2017_Payments 
    ADD TITLE21_Flag varchar(1); 
GO 

UPDATE FY1516..March2017_Payments 
SET TITLE21_Flag = '' 
GO 

UPDATE FY1516..March2017_Payments 
SET TITLE21_Flag = 'Y' 
WHERE program_code IN ('A', 'B', 'C') 

3座与SELECT语句被复制到Excel:

SELECT * 
FROM FY1516..March2017_Payments 

我尝试迄今:

  • @start@endbetween @start and @end
  • @previousMonth给比上月
  • @previousMonthYear的前3个字母给比上月

希望能@previousMonth [email protected] +"_Payments"可以是表名

USE FY1516 

CREATE PROCEDURE NameOfStoredProc 
AS 
    DECLARE @start VARCHAR(8), @end VARCHAR(8), 
      @previousMonth VARCHAR(3), @previousMonthYear VARCHAR(4); 

    SET @start = CONVERT(VARCHAR(8), DATEADD(MONTH, DATEDIFF(MONHT, 0, GETDATE()) - 1, 0), 112) 
    SET @end = CONVERT(VARCHAR(8), DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE()) - 1, -1), 112) 

    SET @previousMonth = LEFT(DATENAME(MONTH, DATEADD(MONTH, -1, GETDATE())), 3) 
    SET @previousMonthYear = YEAR(DATEADD(MONTH, -1, GETDATE())) 
的YYYY
+0

因此,您正在寻找一种基于@previousMonth + @ previousMonthYear +“_ Payments”作为文件名动态创建表的方法? –

+0

是的。这是关键部分。我有一个工作代码存储过程,它使用STATIC表名创建表。但是我不能在同一个过程中包含更新命令,因为表格不是在存储过程中创建的,而是仅在'execute'之后创建的。我想我可以创建第二个存储过程来执行第一个存储过程,并将其更新到创建的表中。 –

+0

看看我的答案。您可以使用一个存储过程。该表将在'sp_executesql'命令之后提供。但是,如果您正在以编程方式执行所有操作,则可能需要在动态SQL中包装任何后续插入或更新。 –

回答

1

你可以通过com将块1和块2合并为一个语句:

--creates payment table 
Select Recipient_ID 
, DOP 
, Provider_ID 
,program_code 
,poverty_code 
,TITLE21_Flag = CASE WHEN program_code IN ('A','B','C') THEN 'Y' ELSE '' END 
INTO FY1516..March2017_Payments 
FROM FY1516..v_all_Claim 
WHERE amount <> 0 and DOP between '20170301' and '20170331' 

然后,在您的proc中,可以使用动态SQL创建表。这里有一个例子:

Create procedure NameOfStoredProc 
AS 
declare @start varchar(8) 
, @end varchar(8) 
,@previousMonth varchar(3) 
,@previousMonthYear varchar(4); 

set @start = convert(varchar(8),dateadd(month, datediff(month,0,getdate())-1,0),112) 
set @end = convert(varchar(8),DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE())-1, -1),112) 
set @previousMonth = left(datename(month, dateadd(month,-1,getdate())), 3) 
set @previousMonthYear = year(dateadd(month,-1,getdate())) 

DECLARE @SQLString NVARCHAR(MAX) = 'CREATE TABLE ' + @previousMonth [email protected] +'_Payments (ColA int)' 
EXECUTE sp_executesql @SQLString 

你会想与你的实际列名和数据类型来代替(ColA int)

编辑:

下面是一个示例,其中包括块1/2到存储过程。它首先检查表的存在,然后运行相应的SELECT查询。

CREATE PROCEDURE NameOfStoredProc 
AS 
begin 
declare @start varchar(8) 
, @end varchar(8) 
,@previousMonth varchar(3) 
,@previousMonthYear varchar(4); 

set @start = convert(varchar(8),dateadd(month, datediff(month,0,getdate())-1,0),112) 
set @end = convert(varchar(8),DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE())-1, -1),112) 
set @previousMonth = left(datename(month, dateadd(month,-1,getdate())), 3) 
set @previousMonthYear = year(dateadd(month,-1,getdate())) 

DECLARE @SQLString NVARCHAR(MAX) = 
'IF OBJECT_ID('''[email protected] [email protected] +'_Payments'', ''U'') IS NOT NULL 
BEGIN 
    print 1 
    INSERT INTO FY1516..'+ @previousMonth [email protected] +'_Payments 
    Select Recipient_ID 
    , DOP 
    , Provider_ID 
    ,program_code 
    ,poverty_code 
    ,TITLE21_Flag = CASE WHEN program_code IN (''A'',''B'',''C'') THEN ''Y'' ELSE '''' END 
    FROM FY1516..v_all_Claim 
    WHERE amount <> 0 and DOP between ''20170301'' and ''20170331'' 
END 
ELSE 
BEGIN 
print 2 
    Select Recipient_ID 
    , DOP 
    , Provider_ID 
    ,program_code 
    ,poverty_code 
    ,TITLE21_Flag = CASE WHEN program_code IN (''A'',''B'',''C'') THEN ''Y'' ELSE '''' END 
    INTO FY1516..'+ @previousMonth [email protected] +'_Payments 
    FROM FY1516..v_all_Claim 
    WHERE amount <> 0 and DOP between ''20170301'' and ''20170331'' 
END 
' 
EXECUTE sp_executesql @SQLString 

SET @SQLString = 'SELECT * FROM '[email protected] [email protected] +'_Payments' 
EXECUTE sp_executesql @SQLString 
END 
+0

亚伦,在你给出的两个代码块中,我自己都明白这两个块,但我不知道如何将两者结合起来。当第一个块有一个'INTO'语句时,我是否在第一个块上写入'INSERT INTO',并将整个块放在第二个块下面?如果是这样的话,在编写'INSERT INTO'时应该如何引用动态表? = D –

+0

我在答案中增加了另一个例子。它将块1/2中的代码合并到动态SQL中。我还添加了一个检查来查看表是否存在,因为我假设存储过程可能在目标表不存在的时候运行,而且当目标表可能存在时,所以我们必须确保我们只创建一个新表如果我们想要的那个还不存在。 –

+1

您提供的代码允许我学习并创建一个工作存储过程,该过程完成了我手动为报表手动执行的所有操作。我非常感谢帮助! –