在字符串中使用单引号时出现奇怪的SQL异常

时间:2016-12-14 11:57:10

标签: c# sql database

我正在向服务器发送消息并将消息上传到数据库, 大多数单词都经过了正确但我注意到当我发送单词时 “这是怎么回事?”它给出了一个错误,但当我发送“什么?”没有T和S之间的单个逗号它运作良好。

有什么问题?

这是我得到的例外: 附加信息:'s'附近的语法不正确。

字符串')'后面的未闭合引号。

我在com.Executenonquery行获得了异常。

string message = bf.Deserialize(client).ToString();
SqlCommand com = new SqlCommand($"insert into messages (messagetext,sentdate) values ('{message}','{DateTime.Now}')",sc);
int success = com.ExecuteNonQuery();
if (success < 1)
{
    MessageBox.Show("Something went wrong");
}

7 个答案:

答案 0 :(得分:3)

你在脚下射击自己。

你的字符串:

$"insert into messages (messagetext,sentdate) values ('{message}','{DateTime.Now}')"
在你通过&#34;什么之后?&#34>?你得到:

insert into messages (messagetext,sentdate) values ('what's up?','...')

请参阅此部分:'what's up?'?撇号也是SQL中字符串的引用。这就是你应该从不使用字符串操作在SQL中输入数据的原因。使用参数或更好的ORM。

答案 1 :(得分:2)

string message = bf.Deserialize(client).ToString();
SqlCommand com = new SqlCommand("insert into messages (messagetext,sentdate) values (@sqlMessage, @sqlDatetime)", sc);
com.Parameters.AddWithValue("@sqlMessage", message);
DateTime myDateTime = DateTime.Now;
var sqlFormattedDate = myDateTime.ToString("yyyy-MM-dd HH:mm:ss");
com.Parameters.AddWithValue("@sqlDataTime", sqlFormattedDate);

int success = com.ExecuteNonQuery();
if (success < 1)
{
    MessageBox.Show("Something went wrong");
}

添加参数可以解决您的问题,您将字符串添加为'hello'而不是hello,例如

答案 2 :(得分:1)

您需要将单引号加倍才能生效,但您应该使用参数化查询。系统将为您处理所有事情,并检查变量的内容以防止SQL脚本注入。

答案 3 :(得分:1)

因为您的输入会生成如下的无效查询..

insert into messages (messagetext,sentdate) values ('what's up?','somedate')

你有没有发现差异?您的单引号会关闭在 what 之前开始的开头引号。要解决此问题,最好使用参数化SQL。

这是一些参考

SQL Injection

答案 4 :(得分:0)

原因是您使用单个'(单引号)而不是double,并且它充当字符串文字的末尾,使SQL无效。您应该使用参数:

  1. 避免SQL注入攻击。
  2. 避免出现您遇到的问题及其他问题(例如格式正确并传递日期\日期时间值)。
  3. 同样在你的代码中检查结果值是没用的,因为你会得到一个例外。修改后的代码:

    int rows = 0;
    string message = bf.Deserialize(client).ToString();
    SqlCommand com = new SqlCommand(@"insert into messages 
       (messagetext,sentdate) 
       values 
       (@message, @sent)", sc);
    com.Parameters.Add("@message",SqlDbType.VarChar).Value = message;
    com.Parameters.Add("@sent",SqlDbType.DateTime2).Value=DateTime.Now;
    try
    {           
        sc.Open();
        rows = com.ExecuteNonQuery();
        sc.Close();
    }
    catch (Exception ex)
    {
        MessageBox.Show("Something went wrong:"+ex.Message);
    }
    if (rows < 1) // this should never happen without an exception - redundant
    {
        MessageBox.Show("Something went wrong - no rows were inserted");
    }
    

答案 5 :(得分:0)

其他人说... 这个问题有几种选择。您可以使用SqlCommand的AddParameterWithValue方法。

  1. 添加参数的选项;

    var sqlString =&#34; INSERT INTO消息(messagetext,sentdate)值(@MesasgeText,@ SentDate)&#34; var messageText = bf.Deserialize(client).ToString(); System.Data.SqlClient.SqlCommand scmd = new System.Data.SqlClient.SqlCommand(sqlString); scmd.Parameters.AddWithValue(&#34; @MesasgeText&#34;,messageText); scmd.Parameters.AddWithValue(&#34; @ SentDate&#34;,DateTime.Now);

  2. 带编码/解码的选项=&gt;如果你将使用这个选项,当你向网站上的最终用户显示messageText时,不要忘记HtmlDecode。

    var messageText = HttpUtility.HtmlEncode(bf.Deserialize(client).ToString());

  3. 希望这可以帮到你, 亲切的问候。

答案 6 :(得分:-1)

看起来你是用C#编写的?

如果是这样,可能是因为'是一个txt分隔符。我猜你可以通过把你的逃脱角色放在那里来解决它。这可能是(?)\所以消息应该是“什么事情”,以便在使用等时不会在你的txt中得到异常。'

在SQL中抛出它时仍然会出错,因为'还有用于定义字符串中的开始/停止。要解决它,你需要设置双'

等等'怎么了!'