2013-07-03 27 views
0

如果我有這樣一個存儲過程:從CLR返回的行數的存儲過程

CREATE PROCEDURE [dbo].[sp_update_dummy] 
AS 
BEGIN 
    update update_dummy set value = value + 1 where id = 1 
END 

,並把這種使用executeUpdate(從標準的java.sql庫),那麼更新的行數返回給Java程序(當然,假定update語句更新表中的一行)。

但是如果我執行CLR存儲過程編碼是這樣的:

[Microsoft.SqlServer.Server.SqlProcedure] 
public static void clr_update_dummy() 
{ 
    using (SqlConnection conn = new SqlConnection("context connection=true")) 
    { 
     SqlCommand command = new SqlCommand("update update_dummy set value = value + 1 where id = 1", conn); 

     conn.Open(); 

     command.ExecuteNonQuery(); 

     conn.Close(); 
    } 
} 

然後Java程序沒有得到更新的行數(它似乎得到的值-1返回)。如果我將SET NOCOUNT ON放入SQL存儲過程中,也會發生這種情況。

因此,在我看來,CLR存儲過程的行爲就好像使用了SET NOCOUNT ON一樣。

是否有任何方法來編寫CLR存儲過程,以便可以採用與SQL存儲過程相同的方式獲取行計數?不幸的是,它不可能改變Java程序(它是第三方組件),例如,拿起一個OUTPUT參數。我看過SqlContext.Pipe,但沒有什麼明顯的。此外,我不確定行計數返回到executeUpdate過程的機制。

我也許可以創造一個黑客繞過這個問題(Java的執行SQL存儲過程,這反過來執行,例如CLR存儲過程),但如果可能的話,我想不會引入其他層到調用堆棧。

+0

旁註:你不應該使用存儲過程的名稱'sp_'前綴 - 它保留了微軟的系統過程。 –

+0

@Damien_The_Unbeliever - 我意識到這一點,我不明智地選擇了這個名字。 –

+0

你需要使用CLR嗎?這只是爲了避免使用SQL? – gbn

回答

0

你可能(如果是有意義的只是轉身從CLR過程中運行一段SQL語句)要調用ExecuteAndSend

除了任何實際結果,其它消息和錯誤也直接發送給客戶。

SqlCommand command = new SqlCommand("update update_dummy set value = value + 1 where id = 1", conn); 
conn.Open(); 

SqlContext.Pipe.ExecuteAndSend(command); 
+0

謝謝,這工作正常,但只有當我使用SqlCommand。對於一些數據庫,我必須使用SqlContext.Pipe不接受的OdbcCommand。有沒有辦法可以看到ExecuteAndSend放入管道?也許如果我打電話給ExecuteReader,然後通過結果集,我會得到一些想法... –

+0

用ExecuteReader替換ExecuteNonQuery並查看返回的SqlDataReader我可以看到一個RecordsAffected整數,它告訴我更新會影響多少行。但是我不確定如何在不使用Pipe.ExecuteAndSend方法的情況下將這些信息返回給調用者。 –

+0

@KeithMiller - 我已經快速瀏覽了'SqlPipe'類,並且似乎沒有任何可能的方法。我所能想到的只是一個醜陋的陷阱 - 手裏有行數信息,構造一個SQL查詢,它會影響相同數量的行並執行它。 –