SQL转换从varbinary到varchar

本文关键字:varchar varbinary 转换 SQL | 更新日期: 2023-09-27 18:13:58

我正在使用一个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搜索都指向转换日期,几乎就好像这是你唯一可以使用转换的东西。

SQL转换从varbinary到varchar

您应该能够使用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/en-us/library/cc716729.aspx

SQL Server char, varchar, ncharnvarchar都映射到/来自c# string(尽管char[]也可以工作)。

SQL Server binary and varbinary map to/from a C# byte[] .

你到底有什么问题?

此外,如果你将二进制数据作为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)参数的值并调用该存储过程—这就是您需要做的全部工作!