2017-05-05 55 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

您提供的代碼允許我學習並創建一個工作存儲過程,該過程完成了我手動爲報表手動執行的所有操作。我非常感謝幫助! –