2013-07-03 3 views
0

Если у меня есть хранимая процедура, как это:Возвращение ROWCOUNT из CLR хранимой процедуры

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

и вызвать используя executeUpdate (из стандартной библиотеки java.sql) обновленное количество строк возвращается в программу Java (предполагая, конечно, что оператор обновления обновляет строку в таблице).

Однако если выполнить процедуру 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

Side Примечание: Вы не должны использовать 'sp_' префикса для сохраненных имен процедур - это зарезервировано для системных процедур Microsoft. –

+0

@Damien_The_Unbeliever - Я знаю об этом, я выбрал это имя неразумно. –

+0

Вам нужно использовать CLR? Это просто избежать использования SQL? – gbn

ответ

0

Вы, вероятно (если это имеет смысл, чтобы просто развернуться и работает кусок SQL внутри вашей процедуры CLR) хочет вызвать ExecuteAndSend

В дополнении к любым фактическим результатам, другие сообщения и ошибки также отправляется непосредственно клиенту.

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

SqlContext.Pipe.ExecuteAndSend(command); 
+0

спасибо, что работает нормально, но только если я использую SqlCommand. Для некоторых баз данных я должен использовать OdbcCommand, который SqlContext.Pipe не принимает. Есть ли способ увидеть, что ExecuteAndSend помещает в трубу? Возможно, если я вызову ExecuteReader, а затем пройду через набор результатов, я получу какую-то идею ... –

+0

Замена ExecuteNonQuery с помощью ExecuteReader и просмотр возвращаемого SqlDataReader. Я вижу целое число RecordAffected, которое сообщает мне, сколько строк затронуло обновление. Однако я не уверен, как вернуть эту информацию вызывающему, не используя метод Pipe.ExecuteAndSend. –

+0

@KeithMiller - Я быстро взглянул на класс 'SqlPipe', и там, похоже, нет никаких вероятных методов. Все, что я могу придумать, - это уродливая папка - с информацией о количестве строк в руке, постройте SQL-запрос, который будет влиять на то же количество строк и выполнить это. –

Смежные вопросы