不允许隐式转换VARCHAR到VARBINARY

时间:2016-06-03 09:22:55

标签: c# sql sql-server sql-insert

我遇到了问题。我正在开发一个ASP.net MVC应用程序来管理文件上传到数据库。没什么大不了的。但是每次执行我的SQL-Command时,他都会告诉我我需要先转换为VARBINARY。

这个问题在这里和互联网上都有很多问题,但我仍然无法让它发挥作用..

这就是我得到的:

SQL表:

DocID               INT             IDENTITY(1,1) NOT NULL, 
DocName             VARCHAR(512)    NOT NULL,
DocData             VARBINARY(max)  NOT NULL,
ContentType         NVARCHAR(100)   NOT NULL,
ContentLength       BIGINT          NOT NULL,
InsertionDate       DATETIME        NOT NULL DEFAULT GETDATE(),                     
CONSTRAINT PK_DOC_STORE PRIMARY KEY NONCLUSTERED (DocID)

使用BinaryReader将文件读取到byte []。

var reader = new BinaryReader(file.InputStream);
var data = reader.ReadBytes(file.ContentLength);

INSERT INTO C#代码:

sqlConnection.Open();

var sqlCommand = new SqlCommand
(
"INSERT INTO DocStore VALUES ('@DocumentName', '@DocumentData', '@DocumentType', '@DocumentSize', '@DocumentDate')"
, sqlConnection
);

sqlCommand.Parameters.AddWithValue("@DocumentName", file.FileName);
sqlCommand.Parameters.AddWithValue("@DocumentData", data);
sqlCommand.Parameters.AddWithValue("@DocumentType", file.ContentType);
sqlCommand.Parameters.AddWithValue("@DocumentSize", file.ContentLength);
sqlCommand.Parameters.AddWithValue("@DocumentDate", DateTime.Now);

var success = sqlCommand.ExecuteNonQuery();

sqlConnection.Close();

这里有什么问题?我看不出问题..对于VARBINARY部分,byte []不应该在这样的参数化命令字符串中工作吗?

2 个答案:

答案 0 :(得分:5)

您在参数名称周围加上引号,这将使它们成为字符串文字。

另外,我建议在insert语句中指定列。如果您没有指定要插入的列,则会从您的表中获取确切的定义(不包括ID字段,因为它是自动递增的)。如果在中间插入字段,则可能会中断查询。

INSERT INTO DocStore (DocName, DocData, ContentType, ContentLength, InsertionDate)
VALUES (@DocumentName, @DocumentData, @DocumentType, @DocumentSize, @DocumentDate)

答案 1 :(得分:2)

<强>解决方案

而不是

var sqlCommand = new SqlCommand
(
"INSERT INTO DocStore VALUES ('@DocumentName', '@DocumentData', '@DocumentType', '@DocumentSize', '@DocumentDate')"
, sqlConnection
);

我会用

var sqlCommand = new SqlCommand
(
"INSERT INTO DocStore VALUES (@DocumentName, @DocumentData, @DocumentType, @DocumentSize, @DocumentDate)"
, sqlConnection
);

为什么?

因为"INSERT INTO ... '@DocumentData' ... "字符串包含T-SQL语句。在T-SQL中,单引号('bla')用于分隔字符串常量的开始和结束,在某些情况下,它也可用于列分隔符。因此,'@DocumentData'表示从SQL Server的角度来看的字符串/ VARCHAR常量。在这种情况下,它会尝试对VARCHAR值('@D...')执行隐式转换VARBINARY(数据类型为DocData列;首先列被跳过,因为它具有IDENTITY属性)。但根据 <{1}}和VARCHAR之间的enter image description here仅允许显式转换。

注意:作为最佳实践,我会明确定义VARBINARY语句的目标列列表。