簡體   English   中英

SQL從varbinary轉換為varchar

[英]SQL CONVERT from varbinary to varchar

我正在使用C#應用程序,它似乎已准備好將圖像插入到數據庫中,但是我的存儲過程吐出了隱式轉換錯誤。 我將圖像讀入字節數組,並將字節數組傳遞給存儲過程。 它需要一個varbinary參數,因此會出現錯誤。 所以我將存儲過程更改為:

ALTER PROCEDURE insertPlayerImage 
      @playerID varchar(9), 
      @profileImage varchar(max), 
      @pending char(1)
AS
    CONVERT(varbinary(max), @profileImage)

INSERT INTO PlayerImage(playerID, profileImage, pending)
VALUES(@playerID, @profileImage, @pending)
GO

這告訴我它期望使用varchar (我的字節數組)並將該數組轉換為varbinary文件。 好吧,我的存儲過程不喜歡我擁有的轉換行。 但是如果我只是做

SELECT CONVERT(varchar, GETDATE());  

有用。 所有的Google搜索都指向轉換日期,幾乎就像您唯一可以使用轉換的日期一樣。

您應該能夠使用varbinary(max)作為參數類型。 如果不是,則在發出Execute之前您沒有正確設置db命令對象或參數。

 public DataTable ExecuteParameterizedStoredProcedureObjects(string procedureName, Dictionary<string, object> parameters)
        {
            var dataTable = new DataTable();
            var _sqlConnection = new SqlConnection(_connectionString);
            var cmd = new SqlCommand(procedureName, _sqlConnection);
            cmd.CommandType = CommandType.StoredProcedure;

            var da = new SqlDataAdapter(cmd);
            foreach (var entry in parameters)
            {
                cmd.Parameters.Add(entry.Key, entry.Value);
            }

            try
            {
                _sqlConnection.Open();
                da.Fill(dataTable);
            }
            catch (Exception ex)
            {
                var errorText = string.Format("Occ Repository ExecuteQuery Error : QueryString={0} :: Error={1}", procedureName, ex.Message);
                throw new Exception(errorText, ex);
            }
            finally
            {
                da.Dispose();
                _sqlConnection.Dispose();
            }

            return dataTable;
        }

用類似這樣的名稱:

 foreach (var record in missingGridEntries)
             {
                 var parameters = new Dictionary<string, object>();
                 parameters.Add("@DataID",int.Parse(record.NodeId));
                 var results = _llDb.ExecuteParameterizedStoredProcedureObjects("listFullPath",parameters);

                 foreach(DataRow dataRow in results.Rows)
                 {
                     record.NodePath = dataRow["fullpath"].ToString();
                     record.NodeFilename = dataRow["name"].ToString();
                 }

             }

您正在使用SQL Server嗎? 如果是這樣,請參閱此頁面以了解SQL數據類型到CLR數據類型的映射: http : //msdn.microsoft.com/zh-cn/library/cc716729.aspx

SQL Server charvarcharncharnvarchar都映射到C# string或從C# string映射(盡管char[]也可以工作)。

SQL Server binary and varbinary map to/from a C#字節[/] map to/from a C#

您遇到的實際問題是什么?

此外,如果要將二進制數據作為varchar傳遞給SQL Server,我希望它會因UTF-16(CLR內部字符串編碼)到SQL Server正在使用的任何代碼頁之間的轉換而變得混亂。

另一件事要注意:您的存儲過程:

ALTER PROCEDURE insertPlayerImage 
  @playerID varchar(9), 
  @profileImage varchar(max), 
  @pending char(1)
AS

  CONVERT(varbinary(max), @profileImage)

  INSERT INTO PlayerImage
  ( playerID , profileImage , pending )
  VALUES
  ( @playerID , @profileImage , @pending )

GO

不是合法的SQL。 Convert()是函數,而不是SQL語句。 它甚至不編譯。 如果您嘗試將varchar參數@profileImage轉換為varbinary ,則必須按照以下步驟進行操作:

 declare @image varbinary(max)
 set @image = convert(varbinary(max),@profileImage)

如果您的存儲過程具有簽名

create procedure dbo.insertPlayerImage

  @playerId     varchar(9) ,
  @profileImage varbinary(max) ,
  @pending      char(1)

as
...

然后這段代碼將為您提供:

public int insertProfileImage( string playerId , byte[] profileImage , bool pending )
{
  if ( string.IsNullOrWhiteSpace(playerId) ) throw new ArgumentException("playerId" ) ;
  if ( profileImage == null || profileImage.Length < 1 ) throw new ArgumentException("profileImage") ;

  int rowCount ;

  string connectString = GetConnectString() ;
  using ( SqlConnection connection = new SqlConnection(connectString) )
  using ( SqlCommand command = connection.CreateCommand() )
  {

    command.CommandType = CommandType.StoredProcedure ;
    command.CommandText = "dbo.insertPlayerImage" ;

    command.Parameters.AddWithValue( "@playerId"     , playerId            ) ;
    command.Parameters.AddWithValue( "@profileImage" , profileImage        ) ;
    command.Parameters.AddWithValue( "@pending"      , pending ? "Y" : "N" ) ;

    rowCount = command.ExecuteNonQuery() ;

  }

  return rowCount ;
}

但是,如果要為圖像數據傳遞null ,則需要更改參數值的設置方式。 類似於以下內容:

command.Parameters.AddWithValue( "@profileImage" , profileImage != null ? (object)profileImage : (object)DBNull.Value ) ;

要么

SqlParameter p = new SqlParameter( "@profileImage" , SqlDbType.VarBinary ) ;
p.Value = DBNull.Value ;
if ( profileImage != null )
{
  p.Value = profileImage ;
}
command.Parameters.Add( p ) ;

OK-您需要這樣做:

存儲過程將參數獲取為varbinary(max)因此您可以將其插入數據庫表的Varbinary(max)列中:

CREATE PROCEDURE insertPlayerImage 
      @playerID varchar(9), 
      @profileImage varbinary(max), 
      @pending char(1)
AS
    CONVERT(varbinary(max), @profileImage)

    INSERT INTO PlayerImage(playerID, profileImage, pending)
    VALUES(@playerID, @profileImage, @pending)

C#代碼獲取在ASP.NET中上載的文件的內容並調用此存儲過程:

// set up connection and command
using(SqlConnection conn = new SqlConnection("your-connection-string-here"))
using(SqlCommand cmd = new SqlCommand("dbo.insertPlayerImage"))
{
    // define parameters
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.Add("@playerID", SqlDbType.VarChar, 9);
    cmd.Parameters.Add("@playerImage", SqlDbType.VarBinary, -1);
    cmd.Parameters.Add("@pending", SqlDbType.Char, 1);

    // set the parameter values
    cmd.Parameters["@playerID"].Value = Session["playerID"].ToString();
    cmd.Parameters["@playerImage"].Value = uplImage.FileBytes;
    cmd.Parameters["@pending"].Value = "Y";

    // open connection, execute stored procedure, close connection
    conn.Open();
    cmd.ExecuteNonQuery();
    conn.Close();
}

確實絕對不需要將上載的文件內容從byte[]為其他任何東西(然后返回!)-只需設置varbinary(max)參數的值並調用該存儲過程-這就是您要做的一切!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM