以下存储过程 pr_generate_sales_order 在2个表中生成记录SO Header& SO数据库DB1的详细信息。然后它出口SO Header&详细记录从DB1到DB2。
每当我尝试从ASP.Net/ C#调用此SP时,它会生成以下错误消息: 名称为“c_customers”的游标不存在,并且不会在数据库中创建任何记录。
但是,如果我在SSMS中执行此存储过程 pr_generate_sales_order ,那么它可以正常工作并在DB1&amp ;; DB2。
问题出在哪里?它与Begin Try Catch ... ???
有关USE [DB1]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- ------------------------------------------------------------------------------------
-- Name: pr_generate_sales_order
-- ------------------------------------------------------------------------------------
-- Parameters:
-- - N/A
--
-- Description:
-- Generate Sales Order in DB1 & DB2
-- ------------------------------------------------------------------------------------
alter procedure [dbo].[pr_generate_sales_order] () as
Begin
-- --------------------------------------------------------------------------------
-- Variable declaration
-- --------------------------------------------------------------------------------
Declare @v_error_number nvarchar(10)
Declare @v_error_message_en nvarchar(1000)
Declare @v_customer_id int
Declare @v_time_log_id int
Declare @v_hourly_rate numeric(18, 5)
Declare @v_total_time numeric(18, 5)
Declare @v_description nvarchar(max)
Declare @tmp_time_log Table
(
time_log_id int,
customer_id int,
sku_id int,
hourly_rate numeric(18, 5),
hours int,
minutes int
)
-- --------------------------------------------------------------------------------
-- Main program
-- --------------------------------------------------------------------------------
Set @v_error_number = '0'
Set @v_error_message_en = ''
Begin Try
Begin Transaction T1
-- ------------------------------------------------------------------------
--
-- ------------------------------------------------------------------------
Insert Into @tmp_time_log
Select tl.time_log_id as time_log_id
, tl.customer_id as customer_id
, tl.sku_id as sku_id -- 24/09/2013
, tl.hourly_rate as hourly_rate
, tl.hours_rounded as hours_rounded
, tl.minutes_rounded as minutes_rounded
From time_log tl
Where tl.transaction_date between '2013-01-06' and getdate()
-- ------------------------------------------------------------------------
-- Open Cursor
-- ------------------------------------------------------------------------
-- ------------------------------------------------------------------------
-- Declare Customer Cursor: Get the list of Customer
-- ------------------------------------------------------------------------
Declare c_customers cursor for
Select distinct IsNull(customer_id, 0)
From @tmp_time_log
Open c_customers
Fetch Next From c_customers Into @v_customer_id
While @@fetch_status = 0
Begin
-- ----------------------------------------------------------------
-- Create Sales Order Header for each Customer
-- ----------------------------------------------------------------
Insert Into sales_order_header ...
-- Get Sales Order Header Id
Set @v_sales_order_header_id = scope_identity()
-- ----------------------------------------------------------------
-- Declare Time Log Cursor: Get the list of Time Log by customer in order to Create
-- ----------------------------------------------------------------
Declare c_time_log cursor for
Select time_log_id as time_log_id
, hourly_rate as hourly_rate
, cast( (cast(tl.hours as numeric(18, 5)) + (cast(tl.minutes as numeric(18, 5)) / 60) ) as numeric(18, 5))
as total_time
, sku_id as sku_id
From @tmp_time_log tl
Where customer_id = @v_customer_id
-- ----------------------------------------------------------------
-- Open Cursor
-- ----------------------------------------------------------------
Open c_time_log
Fetch Next From c_time_log
Into @v_time_log_id, @v_hourly_rate, @v_total_time, @v_sku_id
While @@fetch_status = 0
Begin
-- Create Sales Order Detail for Each SO Header
Insert Into sales_order_detail ....
-- Get the next Cursor
Fetch Next From c_time_log Into @v_time_log_id, @v_hourly_rate, @v_total_time, @v_sku_id
End
-- Close & Deallocate Cursor
Close c_time_log
Deallocate c_time_log
-- Get the next Cursor
Fetch Next From c_customers Into @v_customer_id
End
-- Close & Deallocate Cursor
Close c_customers
Deallocate c_customers
-- ------------------------------------------------------------------------
-- Export Sales Order Header & Detail From DB1 to DB2
-- ------------------------------------------------------------------------
Exec [DB2].[dbo].[pr_import_sales_order_from_db1]
--
Commit Transaction T1
End Try
Begin Catch
-- If Error Found Then Rollback Transaction
If @@TRANCOUNT > 0
Begin
-- Close & Deallocate Cursor
Close c_customers
Deallocate c_customers
-- Rollback
Rollback Transaction T1
End
-- Get Error # & Error Message
Select @v_error_number = ERROR_NUMBER()
, @v_error_message_en = 'An error occurred in ' + ERROR_PROCEDURE() + ': ' + ERROR_MESSAGE()
GOTO Step_END
End Catch
-- ------------------------------------------------------------------------------------------
-- Return: Error # & Error message
-- ------------------------------------------------------------------------------------------
STEP_END:
Select @v_error_number as error_number
, @v_error_message_en as error_message_en
End
GO
答案 0 :(得分:2)
如果您在
处收到错误消息exec [DB2].[dbo].[pr_import_sales_order_from_db1]** //are those asterisks there in your code
然后你已经关闭了&取消分配c_customers,但你打电话给那些关闭& deallocate在catch块中第二次调用,我认为这是问题所在。
在上次评论后编辑
保罗,
您应重新组织Try块的最后4行,如下所示。
<强> ORIGINAL 强>
Close c_customers
Deallocate c_customers
Exec [DB2].[dbo].[pr_import_sales_order_from_db1]
Commit Transaction T1
<强>改性强>
Exec [DB2].[dbo].[pr_import_sales_order_from_db1]
Close c_customers
Deallocate c_customers
Commit Transaction T1
如果您CLOSE
&amp; DEALLOCATE
游标,然后在您的DB2 SPROC中发生错误,您将尝试CLOSE
&amp; DEALLOCATE
游标第二次出现在你的拦截区。
在修改/重新排列的版本中,如果一切正常,您仍将关闭&amp;在COMMIT TRAN
之前释放游标,但如果那个DB2 SPROC呕吐,它将直接跳转到catch块和CLOSE
&amp; catch块中的DEALLOCATE
将按预期工作。