当我输入的数据超过列长度时,在ASP.NET中不会抛出异常。

5
问题很简单。
我的数据库中有一列数据类型为NVARCHAR(20)。当我尝试输入包含22个字符的数据时,它只会忽略最后2个字符而不是抛出异常!
这是正常的吗?如何保护数据库免受此类问题的影响?
附注:当然,我使用验证控件和服务器验证,但我该如何保护数据库?是否有一种更高级的约束条件,可以抛出异常并拒绝输入的日期?
try
{
    using (SqlConnection conn = new SqlConnection(ConnStr))
    {
        string Command = "SET NOCOUNT ON; INSERT INTO [Countries] (CountryName, IsVisible) VALUES (@Name, @IsVisible);";

        using (SqlCommand comm = new SqlCommand(Command, conn))
        {
            comm.Parameters.Add("@Name", System.Data.SqlDbType.NVarChar, 20);
            comm.Parameters["@Name"].Value = Name;

            comm.Parameters.Add("@IsVisible", System.Data.SqlDbType.Bit);
            comm.Parameters["@IsVisible"].Value = IsVisible;

            conn.Open();
            comm.ExecuteNonQuery();

            return "Successfully added " + Name + " to the countries.";

        }
    }
}
catch (SqlException SqlEx)
{
    string ErrorMessage = "";

    for (int i = 0; i < SqlEx.Errors.Count; i++)
    {
        ErrorMessage += SqlEx.Errors[i].Number + " : " + SqlEx.Errors[i].Message + "\n";
    }
    return ErrorMessage;
}

这是我正在使用的代码,顺便说一下,我刚刚尝试从Sql Management Studio直接插入比列长度更大的数据,它实际上显示了你刚才描述的消息!


2
通常情况下,这会抛出一个异常,说数据将被截断。您应该发布您的代码和模式,也许有人可以帮助指出问题。 - Brook
@Brook。看起来代码有问题!请检查我的编辑! - Mazen Elkashef
@gbs,但是我将参数长度设置为数据库中列的长度!...我不认为它完全相同..! - Mazen Elkashef
1
也许你在参数中指定了最大长度,这种做法某种程度上抑制了异常。你是否已经尝试过不使用参数插入相同的数据? - Andre Pena
@Ciwee。你是对的,我没有意识到我可以从Parameter.Add()方法中删除长度。 - Mazen Elkashef
显示剩余4条评论
2个回答

9
问题在这两行之间。
   comm.Parameters.Add("@Name", System.Data.SqlDbType.NVarChar, 20);
   comm.Parameters["@Name"].Value = Name;

SQL Server永远不会看到超过20个字符的内容,.Net正在截断字符串。

我记不得SQLParameter的文档了,用谷歌搜索更快。

http://www.eggheadcafe.com/software/aspnet/30873895/sqlparameter-question.aspx

如果您将SqlParam的长度指定为40,则.NET将自动为您截断字符串。不会引发错误(但您可能会丢失数据而不知道)。


哇,我知道发生了什么的简单解释。我只是从ado.net代码的参数中删除了列长度,它就起作用了。它抛出了异常和一切 :D - Mazen Elkashef

2
有几个领域会在数据到达表格之前截断数据,而不会生成错误。
正如@Richard所指出的那样,在您的特定情况下,它被ADO截断了。
如果您调用一个具有varchar(20)参数的存储过程,并传递了22个字符的数据,则SQL服务器中的参数处理引擎也会将其截断。
但是,如果您编写了一个插入状态,尝试直接将22个字符塞入varchar(20)列中,那么您将看到该错误。
基本上,参数处理部分在默默地“修复”它。如果您去掉参数,那么它就会失败。这就是为什么这个问题真正是@gbs提到的那个问题的确切重复。
显然,去掉参数远非理想。

@Chris Lively。+1 感谢您全面地描述了情况...当然我不会牺牲安全性并且删除参数。但是我只是使用了这个>> "comm.Parameters.Add("@Name", System.Data.SqlDbType.NVarChar);",您认为呢? - Mazen Elkashef
@IKashef:我认为这是一个完全有效的解决方案。 - NotMe
是 @gb s 提到了重复的问题,而这个问题被 @gb n 回答了! - Martin Smith
@Martin。这两个问题和答案都涉及相同的主题,而且问题和答案非常接近。但是StackOverflow只会认为一个问题是重复的,如果它是完全相同的,既不是问题也不是答案。你能告诉我一个新手从@gb的引用问题中获得了什么好处吗?很抱歉,没有 :)..我不是那么厉害,我真的没有从我的ADO.NET代码调整中获得任何有益的单词,并且这里提供了最简单的方法以及一些指出重要观点的答案! - Mazen Elkashef
@Martin:谢谢你修复了那个问题。我把他和这里的另一个成员搞混了。 - NotMe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接