我使用的是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());
有用。 所有的谷歌搜索点回转换之日起,仿佛它您可以使用一个转换的唯一的事情。
你使用SQL Server? 如果是这样,看到这个网页的SQL数据类型CLR数据类型映射: http://msdn.microsoft.com/en-us/library/cc716729.aspx
SQL Server的char
, varchar
, nchar
和nvarchar
都映射到/从C# string
(虽然char[]
也能发挥作用)。
SQL Server的binary and
VARBINARY 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 ) ;
您应该能够使用的varbinary(最大值)作为参数类型。 如果没有,那么你是不是发出执行之前正确设置你的数据库命令对象或参数。
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();
}
}
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)
参数并调用存储过程-这就是你需要做的!