我遇到了问题。我正在开发一个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 []不应该在这样的参数化命令字符串中工作吗?
答案 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
之间的仅允许显式转换。
注意:作为最佳实践,我会明确定义VARBINARY
语句的目标列列表。