C # .Net SQL 2012 R2 - вставить файл - System.Data.SqlClient.SqlException: произошла ошибка транспортного уровня при получении результатов с сервера - PullRequest
0 голосов
/ 24 октября 2019

Я пытаюсь вставить файл в поток файлов sql. Файл, который я использовал в своих тестах, имеет размер всего 87 КБ.

У меня есть экземпляр SQL Server 2012 Enteprise, работающий на серверах Windows 2012 R2 и веб-сервере (2012 R2). Приложение, работающее в Интернете, выполняет сотни транзакций в минуту с SQL Server без проблем.

Каждый раз, когда я пытаюсь выполнить хранимую процедуру, которая принимает параметр varbinary (max), я получаю эту ошибку ...

"System.Data.SqlClient.SqlException: ошибка транспортного уровня при получении результатов от сервера. (Поставщик: поставщик TCP, ошибка: 0 - существующее соединение было принудительно закрытоудаленный хост.) ---> System.ComponentModel.Win32Exception: существующее соединение было принудительно закрыто удаленным хостом "

Мне удалось избежать ошибки, когда я удалился в varbinary(max) изSPROC. Вот почему я могу прийти к выводу, что это моя проблема.

Я получаю ту же проблему, пытаясь преобразовать varbinary в base64 varchar(max)

Примеры кода. ..

Это попытка вызвать хранимую процедуру синхронно.

//
//This is an attempt to call the stored procedure synchronously.
public static void InsertFile1(string ProjectKey, string FileName, string ClientID, string FileType, Byte[] File, int FileCategoryId)
{
    try
    {

        SqlConnection conn = null;
        SqlDataReader rdr = null;

        try
        {
            conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ToString());
            conn.Open();
            SqlCommand cmd = new SqlCommand("SPROC", conn);
            cmd.CommandType = CommandType.StoredProcedure;

            cmd.Parameters.Add("@ProjectKey", SqlDbType.VarChar, 30).Value = ProjectKey;
            cmd.Parameters.Add("@FileName", SqlDbType.VarChar, 300).Value = FileName;
            cmd.Parameters.Add("@ClientID", SqlDbType.VarChar, 300).Value = ClientID;
            cmd.Parameters.Add("@FileType", SqlDbType.VarChar, 300).Value = FileType;
            cmd.Parameters.Add("@File", SqlDbType.VarBinary, -1).Value = File;
            cmd.Parameters.Add("@FileCategoryId", SqlDbType.Int, 5).Value = FileCategoryId;

            rdr = cmd.ExecuteReader();
        }
        catch (Exception ex)
        {
            throw new Exception("InsertClientFileVoid3", ex);
        }
        finally
        {
            if (conn != null)
            {
                conn.Close();
            }
            if (rdr != null)
            {
                rdr.Close();
            }
        }

    }
    catch (Exception ex)
    {
        throw new Exception("InsertClientFile", ex);
    }
}

Это попытка вызвать хранимую процедуру асинхронно.


//
//This is an attempt to call the stored procedure asynchronously.
public static void InsertFile2(string ProjectKey, string FileName, string ClientID, string FileType, Byte[] File, int FileCategoryId)
{
    try
    {
        E2EStream(CancellationToken.None,  ProjectKey,  FileName,  ClientID,  FileType, File, FileCategoryId).Wait();
    }
    catch (Exception ex)
    {
        throw new Exception("InsertFile", ex);
    }
}

//
//Function that does the async call to sql

 private static async Task E2EStream(CancellationToken cancellationToken, string ProjectKey, string FileName, string ClientID, string FileType, Byte[] File, int FileCategoryId)
{
    using (SqlConnection writeConn = new SqlConnection(ConfigurationManager.ConnectionStrings["ETLWarehouseSalesforce"].ToString()))
    {
        Task openWriteConn = writeConn.OpenAsync(cancellationToken);
        await Task.WhenAll(openWriteConn);

        using (SqlCommand writeCmd = new SqlCommand("[Publishing].[Insert_File]", writeConn))
        {

            writeCmd.CommandType = CommandType.StoredProcedure;

            writeCmd.Parameters.Add("@ProjectKey", SqlDbType.VarChar, 30).Value = ProjectKey;
            writeCmd.Parameters.Add("@FileName", SqlDbType.VarChar, 300).Value = FileName;
            writeCmd.Parameters.Add("@ClientID", SqlDbType.VarChar, 300).Value = ClientID;
            writeCmd.Parameters.Add("@FileType", SqlDbType.VarChar, 300).Value = FileType;
            writeCmd.Parameters.Add("@File", SqlDbType.VarBinary, -1).Value = File;
            writeCmd.Parameters.Add("@FileCategoryId", SqlDbType.Int, 5).Value = FileCategoryId; 

            await writeCmd.ExecuteNonQueryAsync(cancellationToken);
        }

    }
}

Этохранимая процедура, которая вызывается из C #


--
--This is the stored procedure that is called from C#
CREATE PROCEDURE [dbo].[InsertFile]
    @ProjectKey varchar(30) = ''
    ,@FileName varchar(300) = ''
    ,@ClientID varchar(300) = ''
    ,@FileType varchar(300) = ''
    ,@File varbinary(MAX) = null
    ,@FileCategoryId int = 1
AS
BEGIN

    print 'Stuff will happen here';

END

Вызов этой версии процедуры работает.


--
--This is the stored procedure that is called from C#
CREATE PROCEDURE [dbo].[InsertFile]
    @ProjectKey varchar(30) = ''
    ,@FileName varchar(300) = ''
    ,@ClientID varchar(300) = ''
    ,@FileType varchar(300) = ''
    --,@File varbinary(MAX) = null
    ,@FileCategoryId int = 1
AS
BEGIN

    print 'Stuff will happen here';

END

Обход хранимой процедуры в DB-A

USE [DB-A]

ALTER PROCEDURE [Publishing].[Insert_File]
    @ProjectKey varchar(30) = ''
    ,@FileName varchar(300) = ''
    ,@ClientID varchar(300) = ''
    ,@FileType varchar(300) = ''
    ,@File varbinary(MAX) = null
    ,@FileCategoryId int = 1
AS
BEGIN
    EXEC [DB-B].[Publishing].[Insert_File] @ProjectKey, @FileName, @ClientID, @FileType, @File, @FileCategoryId;
END

- Сообщение об ошибке -

System.Data.SqlClient.SqlException: ошибка транспортного уровня при получении результатов с сервера. (поставщик: поставщик TCP, ошибка: 0 - существующее соединение было принудительно закрыто удаленным хостом.) ---> System.ComponentModel.Win32Exception: существующее соединение было принудительно закрыто удаленным хостом

...