Hello!
I'm hoping someone has wrangled this procedure in the past and can help me troubleshoot - it appears that it's stopped running. In the recent past it ran each time a constituent record was updated - which was less than ideal in many ways - and along the way called another procedure which cleaned up any name and address data entry messes so that the contact information conforms to our consortium data standard.
In doing some related digging this week, I've found that it seems to be neither updating rank nor calling the cleanup function at the expected time. In looking at the trigger on T_CUSTOMER, as well as the code for LP_CUSTOMER_RANK, I don't see anything obvious that would be stopping it.
I should also note that I can't get LP_CUSTOMER_RANK to do what it should (update rank, at a minimum, plus call the other function) even when manually executing it through SSMS.
Any ideas where I should start?
Thanks!
Stacey Voigt
svoigt@granadasb.org
The plot thickens... or thins, depending on your point of view.
This is the statement that is stopping procedure from working. Is it needed? When would a customer number ever be null?
IF @customer_no is null BEGIN EXEC AP_SET_CONTEXT 'LockTrigger', 'N' RETURN END
IF @customer_no is null
BEGIN
EXEC AP_SET_CONTEXT 'LockTrigger', 'N'
RETURN
END
Everything works as expected when I comment this block out. Thoughts? Will I cause database Armageddon if I leave it commented out? Obviously I'm doing this in Test, but it's hard to simulate reality in a Test system that's only got a few users in it at a time.
If commenting out that block is solving your problem, then that means that customer_no IS null whenever the procedure is failing for you!
If it wasn't null, that block wouldn't be executing anyway.
The LockTrigger context flag is used to bypass table triggers for some tables like T_ADDRESS, T_EADDRESS, T_PHONE and a few others. Any procedure or script that sets it to 'Y' should set it back to 'N' when it's done if there is any other work to be done in the database connection.
It's use here is a little confusing since out of the box in 12.5.1, (and as far as I can tell -- someone please correct me) LP_CUSTOMER_RANK is only called by the update trigger on T_CUSTOMER, and that trigger does not check LockTrigger at all. So LockTrigger here may be a red herring, and the real problem is why is your @customer_no variable NULL, causing the procedure to return early!?
If you upload or include the full SQL script I might be able to help further. You might also want to check the TG_CUSTOMER_UPDATE trigger, since that should be what calls LP_CUSTOMER_RANK with the populated @customer_no parameter.
Hi Nick,
Here's the full script. As with the majority of the custom procedures in our database, I inherited this - so it's always a voyage of discovery when something stops working.
Thank you for your help!
--Stacey
RETURNEXEC AP_SET_CONTEXT 'LockTrigger', 'Y'
EXEC AP_SET_CONTEXT 'LockTrigger', 'Y'
--this is the statement that appears to be stopping procedure from working. Is it needed? When would a customer number ever be null?IF @customer_no is null BEGIN EXEC AP_SET_CONTEXT 'LockTrigger', 'N' RETURN END
--this is the statement that appears to be stopping procedure from working. Is it needed? When would a customer number ever be null?
declare @ranking int--select @ranking = 0 declare @rank_type intselect @rank_type = 1 -- Other rank types can be added select @ranking = CASE WHEN ISNULL(sum(1000 - b.rank), 0) < 0 THEN 0 ELSE ISNULL(sum(1000 - b.rank), 0) END from vx_const_cust_active a JOIN tr_constituency b ON a.constituency = b.idwhere customer_no = @customer_no --select @ranking
declare @ranking int
--select @ranking = 0
declare @rank_type int
select @rank_type = 1 -- Other rank types can be added
select @ranking = CASE WHEN ISNULL(sum(1000 - b.rank), 0) < 0
THEN 0
ELSE ISNULL(sum(1000 - b.rank), 0) END
from vx_const_cust_active a
JOIN tr_constituency b ON a.constituency = b.id
where customer_no = @customer_no
--select @ranking
delete t_cust_rankwhere customer_no = @customer_no and rank_type = @rank_type IF @ranking > 0 -- 0 is the default ranking so we don't need to write these records insert t_cust_rank(customer_no, rank_type, rank) select @customer_no, @rank_type, @ranking
delete t_cust_rank
where customer_no = @customer_no and
rank_type = @rank_type
IF @ranking > 0 -- 0 is the default ranking so we don't need to write these records
insert t_cust_rank(customer_no, rank_type, rank)
select @customer_no, @rank_type, @ranking
declare @auto_address_keyword intset @auto_address_keyword = 319
declare @auto_address_keyword int
set @auto_address_keyword = 319
declare @update_address intset @update_address = 1 -- assume we update
declare @update_address int
set @update_address = 1 -- assume we update
declare @original_street1 nvarchar(1024)declare @original_street2 nvarchar(1024)declare @original_street3 nvarchar(1024)declare @original_city nvarchar(1024)declare @new_street1 nvarchar(1024)declare @new_street2 nvarchar(1024)declare @new_street3 nvarchar(1024)declare @new_city nvarchar(1024)declare @address_no int
declare @original_street1 nvarchar(1024)
declare @original_street2 nvarchar(1024)
declare @original_street3 nvarchar(1024)
declare @original_city nvarchar(1024)
declare @new_street1 nvarchar(1024)
declare @new_street2 nvarchar(1024)
declare @new_street3 nvarchar(1024)
declare @new_city nvarchar(1024)
declare @address_no int
if exists ( select * from tx_cust_keyword where customer_no = @customer_no and keyword_no = @auto_address_keyword and key_value = 'No' ) set @update_address = 0 -- no auto update
if exists ( select *
from tx_cust_keyword
and keyword_no = @auto_address_keyword
and key_value = 'No'
)
set @update_address = 0 -- no auto update
if @update_address = 1begin -- get the street address and address number select @address_no = address_no, @original_street1 = street1, @original_street2 = street2, @original_street3 = street3, @original_city = city from t_address where customer_no = @customer_no and primary_ind = 'Y'
if @update_address = 1
begin -- get the street address and address number
select
@address_no = address_no,
@original_street1 = street1,
@original_street2 = street2,
@original_street3 = street3,
@original_city = city
from t_address
where customer_no = @customer_no and primary_ind = 'Y'
if @original_street1 is null -- null address, don't bother set @update_address = 0end
if @original_street1 is null -- null address, don't bother
set @update_address = 0
end
if @update_address = 1begin -- compute new address set @new_street1 = dbo.lf_titlecase (@original_street1, 'street') set @new_street2 = dbo.lf_titlecase (@original_street2, 'street') set @new_street3 = dbo.lf_titlecase (@original_street3, 'street') set @new_city = dbo.lf_titlecase (@original_city, 'city')
begin -- compute new address
set @new_street1 = dbo.lf_titlecase (@original_street1, 'street')
set @new_street2 = dbo.lf_titlecase (@original_street2, 'street')
set @new_street3 = dbo.lf_titlecase (@original_street3, 'street')
set @new_city = dbo.lf_titlecase (@original_city, 'city')
-- if no change, no update if @new_street1 = @original_street1 and @new_street2 = @original_street2 and @new_street3 = @original_street3 and @new_city = @original_city set @update_address = 0end
-- if no change, no update
if @new_street1 = @original_street1 and @new_street2 = @original_street2 and @new_street3 = @original_street3 and @new_city = @original_city
if @new_street1 is null set @update_address = 0
if @new_street1 is null
if @update_address = 1 -- do we need to update?begin update t_address set street1 = @new_street1, street2 = @new_street2, street3 = @new_street3, city = @new_city where address_no = @address_noend
if @update_address = 1 -- do we need to update?
begin
update t_address
set street1 = @new_street1,
street2 = @new_street2,
street3 = @new_street3,
city = @new_city
where address_no = @address_no
GO
Based on Caryl Jones' suggestions, I moved things around so that
IF @customer_no is null RETURN
is at the very beginning; followed by
and
is at the very end of the procedure.
This seems to have solved the problem....
Now I need to go learn about triggers so I'm not fumbling next time this happens! Thank you all.
I think I remember seeing null customer numbers when orders were done at door to general public or via TNEW guest checkout. Please correct me if I'm wrong though.
That script looked like you had an uncommented RETURN statement right at the top! The procedure would have been exiting right there without running anything. (If you ever need to provide a script in the future, it's also a good idea to start with the ALTER PROCEDURE line so that the parameter definition is included.)
Glad your fix worked!
Oh yeah - I can see how that would be a problem! The mystery is how it got there...
I really appreciate everyone's help. It's priceless!