2013-09-26 27 views
1

以下存儲過程pr_generate_sales_order在2個表中生成記錄SO標頭& SO數據庫DB1的詳細信息。然後它輸出SO標頭&詳細記錄從DB1到DB2。從C#/ ASP.NET調用存儲過程的錯誤

每當我打電話從ASP.Net/ C#這個SP它生成以下錯誤消息: 名爲「c_customers」遊標不存在沒有記錄將在數據庫中創建。

但是,如果我執行在SSMS此存儲過程pr_generate_sales_order directy然後正常工作,它在DB1 & DB2生成的記錄。

問題在哪裏?它與開始嘗試捕捉有關...?

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 

回答

2

如果你在

exec [DB2].[dbo].[pr_import_sales_order_from_db1]** //are those asterisks there in your code 

的錯誤,那麼你已經關閉&解除分配c_customers,但你去調用那些接近& DEALLOCATE調用第二次在你的catch塊,這是我承擔是問題。

編輯最後的評論後

保羅,

應重新組織最後4行的try塊如下。

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 & DEALLOCATE光標,然後在出現錯誤的DB2 SPROC,您將嘗試使用CLOSE & DEALLOCATE t他在你的catch塊中第二次光標。

在修改/重排版本,如果一切正常,你仍然接近&解除分配之前光標到您的COMMIT TRAN,但如果DB2存儲過程pukes,它會直接跳轉到catch塊和CLOSE & catch塊中的DEALLOCATE將按預期工作。

+2

只是爲了增加這一點,OP將要檢查他的連接字符串正在使用的用戶帳戶,看它是否實際上有權訪問DB2(和那個過程)。我懷疑'pr_import_sales_order_from_db1'失敗的原因是由於權限問題。 – NotMe

+0

好點chris –

+0

@ChrisLively:你說得對!最初,我使用DB1的用戶在C#中調用SP。所以,現在,我嘗試使用用戶SA,它工作正常,它在DB1和DB2中創建記錄!另外,我保持關閉&Deqallocate光標在回滾部分...謝謝克里斯 – Paul