У меня есть хранимая процедура:
CREATE PROCEDURE [dbo].[brbackup]
@dataID [nvarchar](max),
@backupdata [varbinary](max) OUTPUT
WITH EXECUTE AS CALLER
AS
EXTERNAL NAME [SQLBackupRestore].[StoredProcedures].[BackupStuff]
GO
Что отображается обратно в этот код хранимой процедуры CLR:
public class StoredProcedures
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void BackupStuff(string dataID, out byte [] backupdata)
{
[..body omitted..]
}
}
Это работает просто отлично, я могу назвать это в t-sql на сервере просто так:
declare @backupdata varbinary(max);
exec brbackup "dataIDNumber", @backupdata output;
Я получаю ожидаемый вывод (несколько мегабайт данных в @backupdata). То, что я хотел бы сделать, это вызвать это из C # через клиента, но это не работает:
static void Main(string[] args)
{
SqlConnection conn = new SqlConnection("myConnString");
conn.Open();
SqlCommand cmd = new SqlCommand("brbackup", conn);
cmd.CommandTimeout = 0;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@dataID", "dataIDNumber");
SqlParameter p = new SqlParameter("@backupdata",
SqlDbType.VarBinary, -1);
p.Direction = ParameterDirection.Output;
cmd.Parameters.Add(p);
cmd.ExecuteNonQuery();
}
Этот запрос не выдает ошибку и выполняется некоторое время (как и ожидалось), но в p.Value
нет ничего, кроме byte[0]
. Я пробовал разные варианты установки длины, отличной от -1, и установки p.Value
на byte[]
, достаточно большой, чтобы сохранить результаты, но не радость.
Однако, как ни странно, создание небольшой хранимой процедуры t-sql для обертывания хранимой процедуры CLR работает:
CREATE PROCEDURE AA_JUST_TESTING
@stuff varbinary(max) output
AS
BEGIN
declare @backupdata varbinary(max);
exec brbackup 'dataIDNumber', @backupdata output;
set @stuff = @backup;
END
GO
А затем вызывать оболочку AA_JUST_TESTING с этим кодом C #:
SqlConnection conn = new SqlConnection("myConnString");
conn.Open();
SqlCommand cmd = new SqlCommand("AA_JUST_TESTING", conn);
cmd.CommandTimeout = 0;
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter p = new SqlParameter("@stuff",
SqlDbType.VarBinary, -1);
p.Direction = ParameterDirection.Output;
cmd.Parameters.Add(p);
cmd.ExecuteNonQuery();
Работает просто персик. p.Value
получается с byte []
нужного размера, заполненного правильными данными.
Итак ... Я не вижу разницы, кроме того, что один вызывает хранимую процедуру CLR, а другой вызывает хранимую процедуру T-SQL, хотя они оба используют varbinary(max) output
для возврата значения. Я ищу:
Правдоподобное объяснение, указатель на документацию и т. Д. ... которое говорит мне, почему это работает так.
Какой-то обходной путь, поэтому мне не нужно иметь хранимую процедуру-обертку, и я могу просто выполнить то, что мне нужно, вызывая CLR SP непосредственно из C #.