消息102,级别15,状态1,行1'''附近的语法不正确

时间:2012-11-12 19:51:51

标签: sql-server stored-procedures

我正在尝试创建一个包含动态查询的存储过程。我使用动态查询的原因是我需要将0到3个参数传递给同一个查询。

现在,当我运行该程序时,我收到以下错误:

  

Msg 102,Level 15,State 1,Line 1
  ')'附近的语法不正确。

我的错误在哪里?

CREATE PROCEDURE [harris].[ebill](@cycle_ char(15),@route_ char(15),@account_ char(64))
As
SET NOCOUNT on
Begin
--variable declarations
declare @SQLQuery NVarchar(4000)

declare @errcount int
declare @count_2 int
declare @jour_no int
declare @cnt int
declare @loop_counter int
declare @loop_count int
declare @trans_date_count int
declare @batch_number_count int

declare @account_no char (10)
declare @occupant_code char(2)
declare @name char(30)
declare @email_address char(70)
declare @serv_street_no char(5)
declare @serv_street_mod char(3)
declare @serv_street char(20)
declare @batchnumber char(10)

declare @net numeric(18,2)
declare @owing numeric(18,2)

declare @trans_date datetime
declare @ebill_date_sent datetime
declare @duedate datetime
declare @billdate datetime

--cursors being used for recordsets 
declare @ebill_list_cur CURSOR
declare @trans_date_cur CURSOR
declare @rs_cur CURSOR

--temp table to store recordset being returned
create table #ebill_list
(
   account_no char(10), 
   occupant_code char(2), 
   name char(30), 
   email_address char(70),
   serv_street_no char(5), 
   serv_street_mod char(3), 
   serv_street char(20), 
   net numeric(18,2), 
   owing numeric(18,2), 
   duedate datetime, 
   billdate datetime
)

create table #ebill_templist
(
   account_no char(10), 
   occupant_code char(2), 
   name char(30), 
   email_address char(70),
   serv_street_no char(5), 
   serv_street_mod char(3), 
   serv_street char(20)
)


-- Create cursor of ebill customers  

Set @SQLQuery = 'select account_no, occupant_code, [name], email_address, serv_street_no, serv_street_mod, serv_street '
Set @SQLQuery = @SQLQuery + 'from pu_account, wbaccesm '
Set @SQLQuery = @SQLQuery + 'where pu_account.debtor_no = wbaccesm.debtor_no '
Set @SQLQuery = @SQLQuery + 'and wbaccesm.email_notice in (''B'',''Y'')' 

if @cycle_ <> ''
  begin
    Set @SQLQuery = @SQLQuery + ' and pu_account.cycle_ in ('
    Set @SQLQuery = @SQLQuery + @cycle_ +')'
  end

if @route_ <> ''
  begin
    Set @SQLQuery = @SQLQuery + ' and pu_account.route_ in ('
    Set @SQLQuery = @SQLQuery + @route_ +')'
  end

if @account_ <> ''
  begin
    Set @SQLQuery = @SQLQuery + ' and pu_account.account_no in ('
    Set @SQLQuery = @SQLQuery + @account_ +')'
  end

SET @SQLQuery = 'SELECT account_no, occupant_code, [name], email_address, serv_street_no, serv_street_mod, serv_street INTO #ebill_templist FROM (' + @SQLQuery + ')'

EXECUTE sp_executesql @SQLQuery

set @errcount = 0
set @ebill_list_cur = cursor fast_forward
    for
       select account_no, occupant_code, name, email_address, serv_street_no, serv_street_mod, serv_street from #ebill_templist
    open @ebill_list_cur
    fetch next from @ebill_list_cur
        into @account_no,@occupant_code,@name,@email_address,@serv_street_no,@serv_street_mod, @serv_street

-- Loop through the cursor to see who gets ebill

while @@fetch_status=0
begin


    --Check to see if the account is active
    set @cnt = (select count(*) 
    from pu_account_pay
    where account_no=@account_no
    and occupant_code=@occupant_code
    and end_date is null)

    --if account active proceed
    if @cnt>0 
    begin
        --gets a count of records in the pu_balance_host table for the account
        set @trans_date_count=(select count(*)
            from pu_balance_hist
            where account_no =@account_no
            and occupant_code =@occupant_code
            and trans_date in(select max(last_bill_date) 
                from pu_account_pay
                where account_no =@account_no
                and occupant_code =@occupant_code))

        --if more then 0 then proceed
        if @trans_date_count>0
        begin
            --cursor for transaction date
            set @trans_date_cur = cursor fast_forward

            for select trans_date, jour_no
                from pu_balance_hist
                where account_no =@account_no
                and occupant_code =@occupant_code
                and jour_code='BJ'
                and trans_date in(select max(last_bill_date) 
                    from pu_account_pay
                    where account_no =@account_no
                    and occupant_code =@occupant_code)
            open @trans_date_cur

            fetch next from @trans_date_cur into @trans_date, @jour_no

            begin
                    --get batch number count in pujhhdrh table
                    set @batch_number_count=(select count(*) from pujhhdrh
                        where journalnumber = @jour_no
                    and batchtype = 'BJ')

                    -- if count of batch number is greater then 0 proceed
                    if @batch_number_count>0 
                    begin
                        --get batch number
                        set @batchnumber=(select batchnumber
                        from pujhhdrh
                        where journalnumber = @jour_no
                    and batchtype = 'BJ')

                        set @count_2=(select count(*)
                            from pu_ebill_sent
                            where account_no = @account_no
                            and occupant_code = @occupant_code)

                    --get date from pu_ebill_sent
                    if @count_2 > 0
                    begin
                        set @ebill_date_sent=(select max(ebilldate_sent) 
                        from pu_ebill_sent
                        where account_no = @account_no
                        and occupant_code = @occupant_code)

                    end
                    --if no date then set it to last billing date less 1 day
                    else
                    begin
                        set @ebill_date_sent=@trans_date-1
                    end 

                    --if transdate is greater then last ebill date and last trans date is less then todays then send ebill
                    if @trans_date > @ebill_date_sent
                    begin
                        set @rs_cur = cursor fast_forward
                        for select sum(net) net, sum(owing) owing, max(duedate) duedate, max(billdate) billdate
                        from pujhaccd
                            where batchnumber = @batchnumber
                            and account_no = @account_no
                            and occupant_code = @occupant_code
                            and (billtype > 0 and billtype != 3)
                        open @rs_cur
                        fetch next from @rs_cur into @net, @owing, @duedate, @billdate
                        insert into #ebill_list values(
                        @account_no,@occupant_code,@name,@email_address,@serv_street_no,@serv_street_mod, @serv_street,@net, @owing, @duedate, @billdate)

                            fetch next from @ebill_list_cur
                                into @account_no,@occupant_code,@name,@email_address,@serv_street_no,@serv_street_mod, @serv_street
                    end
                    else
                    begin
                        fetch next from @ebill_list_cur
                                into @account_no,@occupant_code,@name,@email_address,@serv_street_no,@serv_street_mod, @serv_street
                        end     
                end

                --if count of batch number is 0 then proceed to the next record in the original cursor
                else
                begin
                    fetch next from @ebill_list_cur
                        into @account_no,@occupant_code,@name,@email_address,@serv_street_no,@serv_street_mod, @serv_street
                    end

            end
        end

        --If no records in pu_balance_his then go to the next record
        else
        begin
            fetch next from @ebill_list_cur
                into @account_no,@occupant_code,@name,@email_address,@serv_street_no,@serv_street_mod, @serv_street
            end


    end 
    -- if not active then go to next record in the cursor
    else
    begin
        fetch next from @ebill_list_cur
                into @account_no,@occupant_code,@name,@email_address,@serv_street_no,@serv_street_mod, @serv_street
        end
    --end for the while loop
    end

set @loop_count=(select count(*) from #ebill_list)
set @loop_counter=0
while @loop_counter<=@loop_count
begin
    select * from #ebill_list
    return
    set @loop_counter=@loop_counter+1
end


close @rs_cur
deallocate @rs_cur

close @trans_date_cur               
deallocate @trans_date_cur

close @ebill_list_cur
deallocate @ebill_list_cur
end

1 个答案:

答案 0 :(得分:2)

问题可能在于您的动态SQL。要调试它,最好的方法是使用PRINT(或查看探查器)将其输出 - 我怀疑你在参数中有问题,这些参数被传递并连接成裸字符串。

您可以通过使用表值参数来完全避免动态SQL,这些参数可以像常规表一样在查询中加入和使用。由于您使用的是动态SQL,因为您只需要检查列表成员资格(而不是动态选择条件或其他内容),我强烈建议您这样做:

http://msdn.microsoft.com/en-us/library/bb510489.aspx