我正在尝试创建一个包含动态查询的存储过程。我使用动态查询的原因是我需要将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
答案 0 :(得分:2)
问题可能在于您的动态SQL。要调试它,最好的方法是使用PRINT(或查看探查器)将其输出 - 我怀疑你在参数中有问题,这些参数被传递并连接成裸字符串。
您可以通过使用表值参数来完全避免动态SQL,这些参数可以像常规表一样在查询中加入和使用。由于您使用的是动态SQL,因为您只需要检查列表成员资格(而不是动态选择条件或其他内容),我强烈建议您这样做: