【问题标题】:Creating a stored procedure for the first time第一次创建存储过程
【发布时间】:2014-03-01 18:07:14
【问题描述】:

我第一次尝试创建一个存储过程以在 Microsoft SSRS 中生成试算表报告(是的,它也让我感到害怕!)并且遇到了一些困难。以前,我使用 Business Objects 或 MS Access 来促进来自源数据库的报告需求。

以下 CREATE SP 语句中的 SQL 查询运行正确,但在尝试将其转换为新的存储过程时遇到问题:

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:  <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
CREATE PROCEDURE [dbo].[GDM_TrialBalanceEL3_DEV_CVB]

 -- Add the parameters for the stored procedure here
@grpcode varchar(12),
@company varchar(12),
@currency varchar(12),
@begperiod int,
@startperiod int,
@endperiod int

AS
BEGIN
 -- SET NOCOUNT ON added to prevent extra result sets from
 -- interfering with SELECT statements.
 SET NOCOUNT ON;


--- DECLARE VARIABLES ----

DECLARE @NominalLevel int,
        @Currency varchar(3),
        @cmpcode varchar (12),
        @FromYear int,
        @FromPeriod int,
        @FromPeriodMMMM int,
        @ToYear int,
        @ToPeriod int,
        @ToPeriodMMMM int,
        @BookingType varchar (2)

--- SET PARAMETERS  (enter values) ---        

SET @NominalLevel = 3
SET @Currency = 'EUR'
SET @cmpcode = 'BEC001'
SET @FromYear = 2013
SET @FromPeriod = 1
SET @ToYear = 2013
SET @ToPeriod = 12
SET @BookingType = 'STCO'

--- COMBINE PARAMETERS ----

SET @FromPeriodMMMM = @FromYear * 10000 + @FromPeriod
SET @ToPeriodMMMM = @ToYear * 10000 + @ToPeriod

------OPENING BALANCE ----

SELECT a.cmpcode
   ,g.grpcode
   , SUBSTRING(a.el1,1,2) AS 'ST/CO'
   , a.el2
   , a.el3
   , CASE WHEN @NominalLevel=2 THEN a.el2 ELSE a.el3 END AS 'Account'
   , el.sname AS AccountName
   ,'Opening Balance' AS Movement
   , CASE WHEN @Currency='EUR' THEN SUM(a.valuehome) ELSE SUM(a.valuedual) END AS 'Amount'
   , CASE WHEN @Currency='EUR' AND a.deb_cred_ind=160 THEN SUM(a.valuehome)WHEN @Currency<>'EUR' AND a.deb_cred_ind=160 THEN SUM(a.valuedual)ELSE 0 END AS 'Credit'
   , CASE WHEN @Currency='EUR' AND a.deb_cred_ind=161 THEN SUM(a.valuehome)WHEN @Currency<>'EUR' AND a.deb_cred_ind=161 THEN SUM(a.valuedual)ELSE 0 END AS 'Debit'   
   , c.l1hdrtxt
   , c.l2hdrtxt
   , c.l3hdrtxt
   , c.leafhdrtxt

FROM        CODATEST_EU1.dbo.oas_agmlist b,
CODATEST_EU1.dbo.oas_docline a,
CODATEST_EU1.dbo.oas_himlist c,
CODATEST_EU1.dbo.oas_dochead d,
CODATEST_EU1.dbo.oas_perlist e,
CODATEST_EU1.dbo.oas_company f,
CODATEST_EU1.dbo.oas_grplist g,
CODATEST_EU1.dbo.oas_element el

WHERE 
((a.el3 BETWEEN b.el3incfrom AND b.el3incto) 
AND((b.el3excfrom is NULL) OR (a.el3 NOT BETWEEN b.el3excfrom AND b.el3excto)))
AND c.code='TRIALBALANCE'
AND c.grpcode=b.code 
AND a.cmpcode = d.cmpcode
AND a.doccode = d.doccode
AND a.docnum = d.docnum 
AND d.yr = e.yr 
AND d.period = e.period
AND d.cmpcode = e.cmpcode 
AND d.cmpcode = f.code
AND a.el1 = g.code 
AND a.cmpcode= g.cmpcode
AND g.elmlevel = 1
AND d.cmpcode = el.cmpcode 
AND el.code = CASE WHEN @NominalLevel=2 THEN a.el2 ELSE a.el3 END
AND el.elmlevel= @NominalLevel
AND a.cmpcode = @cmpcode
AND d.yr*10000+d.Period BETWEEN f.yrmin*10000  AND (@FromPeriodMMMM-1)
AND        g.grpcode = @BookingType
AND a.el3 < '60000000'        

GROUP BY        a.cmpcode
,g.grpcode
, SUBSTRING(a.el1,1,2) 
, a.el2
, a.el3
, CASE WHEN @NominalLevel=2 THEN a.el2 ELSE a.el3 END
, EL.sname
, a.deb_cred_ind
, c.l1hdrtxt
, c.l2hdrtxt
, c.l3hdrtxt
, c.leafhdrtxt

UNION ALL

----MOVEMENT ----

SELECT a.cmpcode
       ,g.grpcode
   , SUBSTRING(a.el1,1,2) AS 'ST/CO'
   , a.el2
   , a.el3
   , CASE WHEN @NominalLevel=2 THEN a.el2 ELSE a.el3 END AS Account
   , el.sname as AccountName
   ,'Movement' AS Movement
   , CASE WHEN @Currency='EUR' THEN SUM(a.valuehome) ELSE SUM(a.valuedual) END AS 'Amount'
   , CASE WHEN @Currency='EUR' AND a.deb_cred_ind=160 THEN SUM(a.valuehome)WHEN @Currency<>'EUR' AND a.deb_cred_ind=160 THEN SUM(a.valuedual)ELSE 0 END AS 'Credit'
   , CASE WHEN @Currency='EUR' AND a.deb_cred_ind=161 THEN SUM(a.valuehome)WHEN @Currency<>'EUR' AND a.deb_cred_ind=161 THEN SUM(a.valuedual)ELSE 0 END AS 'Debit'
   , c.l1hdrtxt
   , c.l2hdrtxt
   , c.l3hdrtxt
   , c.leafhdrtxt

FROM        CODATEST_EU1.dbo.oas_agmlist b,
CODATEST_EU1.dbo.oas_docline a,
CODATEST_EU1.dbo.Oas_himlist c,
CODATEST_EU1.dbo.oas_dochead d,
CODATEST_EU1.dbo.oas_perlist e,
CODATEST_EU1.dbo.oas_company f,
CODATEST_EU1.dbo.oas_grplist g,
CODATEST_EU1.dbo.oas_element el

WHERE 
((a.el3 BETWEEN b.el3incfrom AND b.el3incto) 
AND((b.el3excfrom is NULL) OR (a.el3 NOT BETWEEN b.el3excfrom AND B.el3excto)))
AND c.code='TRIALBALANCE'
AND c.grpcode=b.code 
AND a.cmpcode = d.cmpcode
AND a.doccode = d.doccode
AND a.docnum = d.docnum 
AND d.yr = e.yr 
AND d.period = e.period
AND d.cmpcode = e.cmpcode 
AND d.cmpcode = f.code
AND a.el1 = g.code 
AND a.cmpcode= g.cmpcode
AND g.elmlevel = 1
AND d.cmpcode = el.cmpcode 
AND el.code = Case When @NominalLevel=2 Then a.el2 else a.el3 end
AND el.elmlevel= @NominalLevel
AND a.cmpcode = @cmpcode
AND d.yr*10000+d.Period between @FromPeriodMMMM and @ToPeriodMMMM
AND        g.grpcode = @BookingType

GROUP BY        a.cmpcode
            ,g.grpcode
, SUBSTRING(a.el1,1,2) 
, a.el2
, a.el3
, CASE WHEN @NominalLevel=2 THEN a.el2 ELSE a.el3 END
, EL.sname
, a.deb_cred_ind
, c.l1hdrtxt
, c.l2hdrtxt
, c.l3hdrtxt
, c.leafhdrtxt

UNION ALL

---- RETAINED EARNINGS ---        

SELECT        a.cmpcode
,g.grpcode
,SUBSTRING(a.el1,1,2) as 'ST/CO'
,(SELECT el1.subselm from oas_element AS el1 WHERE el1.elmlevel=3 AND el1.cmpcode = @cmpcode AND el1.code='53100000')
,'53100000'
, CASE WHEN @NominalLevel=2 THEN (SELECT el1.subselm from oas_element AS el1 WHERE el1.elmlevel=3 AND el1.cmpcode = @cmpcode AND el1.code='53100000')  ELSE '53100000' END AS Account
, CASE WHEN @NominalLevel=2 THEN (SELECT el2.sname FROM oas_element AS el1 ,oas_element AS el2 WHERE el1.elmlevel=3 AND el2.elmlevel=2 AND el1.cmpcode = @cmpcode AND el1.code='53100000' AND el2.code=el1.subselm AND el2.cmpcode = el1.cmpcode)
  ELSE (SELECT el1.sname from oas_element AS el1 WHERE el1.elmlevel=3 AND el1.cmpcode = @cmpcode AND el1.code='53100000')END AS 'AccountName'
, 'Opening Balance'
    , CASE WHEN @Currency='EUR' THEN SUM(a.valuehome) ELSE SUM(a.valuedual) END AS 'Amount'
    , CASE WHEN @Currency='EUR' AND SUM(a.valuehome)<0  THEN SUM(a.valuehome) WHEN @Currency<>'EUR' AND SUM(a.valuedual)<0  THEN SUM(a.valuedual)ELSE 0 END AS 'Credit'
    , CASE WHEN @Currency='EUR' AND SUM(a.valuehome)>0  THEN SUM(a.valuehome) WHEN @Currency<>'EUR' AND SUM(a.valuedual)<0  THEN SUM(a.valuedual)ELSE 0 END AS 'Debit'
, 'BALANCE SHEET'        
, 'EQUITY'
, 'TOTAL RETAINED EARNINGS'
, 'RETAINED EARNINGS'

FROM CODATEST_EU1.dbo.oas_agmlist b,
CODATEST_EU1.dbo.oas_docline a,
CODATEST_EU1.dbo.Oas_himlist c,
CODATEST_EU1.dbo.oas_dochead d,
CODATEST_EU1.dbo.oas_perlist e,
CODATEST_EU1.dbo.oas_company f,
CODATEST_EU1.dbo.oas_grplist g,
CODATEST_EU1.dbo.oas_element el

WHERE 
((a.el3 BETWEEN b.el3incfrom AND b.el3incto) 
AND((b.el3excfrom is NULL) OR (a.el3 NOT BETWEEN b.el3excfrom AND B.el3excto)))
AND c.code='TRIALBALANCE'
AND c.grpcode=b.code 
AND a.cmpcode = d.cmpcode
AND a.doccode = d.doccode
AND a.docnum = d.docnum 
AND d.yr = e.yr 
AND d.period = e.period
AND d.cmpcode = e.cmpcode 
AND d.cmpcode = f.code
AND a.el1 = g.code 
AND a.cmpcode= g.cmpcode 
AND g.elmlevel = 1
AND d.cmpcode = el.cmpcode 
AND el.code = CASE WHEN @NominalLevel=2 THEN a.el2 ELSE a.el3 END
AND el.elmlevel= @NominalLevel
AND a.cmpcode = @cmpcode
AND d.yr*10000+d.Period between f.yrmin*10000 and (@FromPeriodMMMM-1)
AND        g.grpcode = @BookingType
AND a.el3 > '60000000'

GROUP BY        a.cmpcode,g.grpcode,substring(a.el1,1,2)


UNION ALL


---- CY PROFIT/LOSS ---        


SELECT        a.cmpcode
, g.grpcode
, substring(a.el1,1,2) as 'ST/CO'
, (SELECT el1.subselm from oas_element AS el1 WHERE el1.elmlevel=3 AND el1.cmpcode = @cmpcode AND el1.code='53100001')
, '53100001'
, CASE WHEN @NominalLevel=2 THEN(SELECT el1.subselm from oas_element AS el1 WHERE el1.elmlevel=3 AND el1.cmpcode = @cmpcode AND el1.code='53100001') 
  ELSE '53100001' 
  END AS Account
, CASE WHEN @NominalLevel=2 THEN (SELECT el2.sname FROM oas_element AS el1 ,oas_element AS el2 WHERE el1.elmlevel=3 AND el2.elmlevel=2 AND el1.cmpcode = @cmpcode AND el1.code='53100001' AND el2.code=el1.subselm AND el2.cmpcode = el1.cmpcode)
  ELSE (SELECT el1.sname from oas_element AS el1 WHERE el1.elmlevel=3 AND el1.cmpcode = @cmpcode AND el1.code='53100001')END AS 'AccountName'
, 'Movement'
    , CASE WHEN @Currency='EUR' THEN SUM(a.valuehome) ELSE SUM(a.valuedual) END AS 'Amount'
, CASE WHEN @Currency='EUR' AND SUM(a.valuehome)<0  THEN SUM(a.valuehome) WHEN @Currency<>'EUR' AND SUM(a.valuedual)<0  THEN SUM(a.valuedual)ELSE 0 END AS 'Credit'
        , CASE WHEN @Currency='EUR' AND SUM(a.valuehome)>0  THEN SUM(a.valuehome) WHEN @Currency<>'EUR' AND SUM(a.valuedual)<0  THEN SUM(a.valuedual)ELSE 0 END AS 'Debit'
, 'BALANCE SHEET'
, 'EQUITY'
, 'TOTAL RETAINED EARNINGS'
, 'RETAINED EARNINGS'

FROM CODATEST_EU1.dbo.oas_agmlist b,
CODATEST_EU1.dbo.oas_docline a,
CODATEST_EU1.dbo.Oas_himlist c,
CODATEST_EU1.dbo.oas_dochead d,
CODATEST_EU1.dbo.oas_perlist e,
CODATEST_EU1.dbo.oas_company f,
CODATEST_EU1.dbo.oas_grplist g,
CODATEST_EU1.dbo.oas_element el

WHERE 
((a.el3 BETWEEN b.el3incfrom AND b.el3incto) 
AND((b.el3excfrom is NULL) OR (a.el3 NOT BETWEEN b.el3excfrom AND B.el3excto)))
AND c.code='TRIALBALANCE'
AND c.grpcode=b.code 
AND a.cmpcode = d.cmpcode
AND a.doccode = d.doccode
AND a.docnum = d.docnum 
AND d.yr = e.yr 
AND d.period = e.period
AND d.cmpcode = e.cmpcode 
AND d.cmpcode = f.code
AND a.el1 = g.code 
AND a.cmpcode= g.cmpcode
AND g.elmlevel = 1
AND d.cmpcode = el.cmpcode 
AND a.el3 >= '60000000'
AND el.code = CASE WHEN @NominalLevel=2 THEN a.el2 ELSE a.el3 END
AND el.elmlevel= @NominalLevel
AND a.cmpcode = @cmpcode
AND d.yr*10000+d.Period between @FromPeriodMMMM and @ToPeriodMMMM
AND        g.grpcode = @BookingType

GROUP BY a.cmpcode ,g.grpcode , substring(a.el1,1,2)

当尝试运行 SQL 来创建存储过程时,我收到以下消息:

消息 134,级别 15,状态 1,过程 GDM_TrialBalanceEL3_DEV_CVB,第 26 行 变量名称“@Currency”已被声明。变量名称在查询批处理或存储过程中必须是唯一的。 消息 137,级别 15,状态 1,程序 GDM_TrialBalanceEL3_DEV_CVB,第 40 行 必须声明标量变量“@cmpcode”。

注意对于不同的变量,还有大约 10 个额外的 Msg 137 示例,但我想如果我理解 1 的逻辑,我应该能够解决其他 9 个问题?

到目前为止,从我的谷歌研究来看,这可能是由于各种问题(标量变量 = Go 语句强制重新声明变量等),但在检查时没有 GO 语句,只有 UNION 和 JOIN 条件,所以我不知道它适合什么可能的原因。

如果有人能提供帮助(并解释原因,以免我再次犯同样的错误),我将不胜感激,因为我今天迫切需要创建这个 SP,而且似乎 DBA 资源因流感而下降..

【问题讨论】:

  • 你缺少结束括号吗?

标签: sql sql-server tsql stored-procedures


【解决方案1】:

您已将@Currency 声明为两次..删除一次

最后再加一个括号

【讨论】:

  • 嗨,我在“在此处添加存储过程的参数”部分下注释掉了详细信息,它现在一直运行到第 294 行,它在 ')' 附近标记了不正确的语法。你介意看一眼吗? (认为​​这是一个只见树木不见森林的案例!)
【解决方案2】:

将您最后的 WHERE 更改为

WHERE 
((a.el3 BETWEEN b.el3incfrom AND b.el3incto) 
AND((b.el3excfrom is NULL) OR (a.el3 NOT BETWEEN b.el3excfrom AND B.el3excto)) -- one to many here (removed)
AND c.code='TRIALBALANCE'
AND c.grpcode=b.code 
AND a.cmpcode = d.cmpcode
AND a.doccode = d.doccode
AND a.docnum = d.docnum 
AND d.yr = e.yr 
AND d.period = e.period
AND d.cmpcode = e.cmpcode 
AND d.cmpcode = f.code
AND a.el1 = g.code 
AND a.cmpcode= g.cmpcode
AND g.elmlevel = 1
AND d.cmpcode = el.cmpcode 
AND a.el3 >= '60000000'
AND el.code = CASE WHEN @NominalLevel=2 THEN a.el2 ELSE a.el3 END
AND el.elmlevel= @NominalLevel
AND a.cmpcode = @cmpcode
AND d.yr*10000+d.Period between @FromPeriodMMMM and @ToPeriodMMMM
AND        g.grpcode = @BookingType) -- closing bracket here added
GROUP BY a.cmpcode ,g.grpcode , substring(a.el1,1,2)

【讨论】:

  • 试过了,但还是不喜欢——同样的信息,有或没有右括号。
  • 我现在对此感到很尴尬,但我真诚地感谢您的耐心等待!我按照指示复制粘贴了您建议的修改(在删除注释掉的位之后),但恐怕它仍然给出相同的消息(参考第 291 行)
  • 问题已解决。如上所述添加括号后,我添加了“end”并正确完成查询。非常感谢帮助#unsungheroes的人
猜你喜欢
  • 2015-11-25
  • 1970-01-01
  • 1970-01-01
  • 2017-06-19
  • 1970-01-01
  • 1970-01-01
  • 2015-06-14
  • 1970-01-01
  • 2014-06-03
相关资源
最近更新 更多