2016-12-14 51 views
-1

我正在向服务器发送消息并将消息上传到数据库中,大多数单词都正确地通过,但我注意到当我发送单词 “这是怎么回事? “它给出了一个错误,但是当我发送“whats up?”时T和S之间没有单个逗号,它很好。在字符串中使用单引号时出现奇怪的SQL异常

什么问题?

这是我得到的异常: 附加信息:'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"); 
} 
+13

使用参数!不要直接输入查询字符串。您刚刚了解了SQL注入。只需谷歌,并了解更多关于它。 –

+0

除了为SQL注入提供保护外,还允许一些性能改进,以及更多,使用查询中的参数,因为@GordonLinoff建议可以帮助您很多:日期格式化,字符串内部等等,没有问题... –

回答

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例如

+0

附注。 ToString(“yyyy-MM-dd HH:mm:ss”)格式在每个日期和语言设置下都不可靠(特别是如果版本信息未知)。更好的格式是ToString(“yyyyMMdd HH:mm:ss”),更好的是让Date/DateTime或DateTime2类型的参数让驱动程序处理。 –

1

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

+0

我提高了你的建议,但是稍作修改。系统不会检查变量的内容。你传递的东西是纯文本,它会按原样存储(不执行 - 它也可以包含任何脚本)。 –

1

因为你的投入产生像下面一个无效的查询..

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

你观察的区别?您的单引号关闭开头的开头引号,前面的单词什么。要解决此问题,使用参数化SQL始终是最佳做法。

下面是一些参考

SQL Injection

+0

我明白了,谢谢! – NateS

-1

它看起来就像你在C#编码呢?

如果是这样可能是因为'是一个txt分隔符。我想你可以通过把你的转义字符放在那里来解决它。它可能是(?)\所以消息应该是“有什么事”,因为它在使用时不会在你的txt文件中出现异常。'

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

等'什么是'!'

+0

他的确在使用C#,但它与使用的客户端语言无关。你应该简单地使用参数。没有一个开发人员真正将这些值编码为''而不是''。在这种情况下,它也是消息变量,它给出了一个简单应该是参数的悲伤。如果他纠正了它,可能还需要处理日期时间值(这可能在没有给出任何错误但存储错误值的情况下工作 - 未被注意的错误比错误更糟糕)。 –

3

你在脚下射击自己。

您的字符串:

$"insert into messages (messagetext,sentdate) values ('{message}','{DateTime.Now}')" 

传递后 “什么事?”你得到:

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

看到这个零件:'what's up?'?撇号也是SQL中字符串的引用。这就是您应该的原因切勿使用字符串操作在SQL中放入数据。使用参数或更好的ORM。

+0

我认为主要原因是防止SQL注入。 – jarlh

+0

@jarlh井OP只是SQL注入自己。 – Andrey

0

原因是使用的是单'(单引号),而不是双和充当字符串文字的结尾,导致SQL无效。您应该使用参数:

  1. 避免SQL注入攻击。
  2. 避免像刚刚遇到的问题和更多(如正确格式化和传递日期\日期时间值)。

此外,在你的代码检查结果值是没用的,因为你会得到一个异常。修正的代码:

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"); 
} 
0

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

  1. 选项加入参数; (MessageText,senddate)values(@MesasgeText,@SentDate)“ var messageText = bf.Deserialize(client).ToString(); System.Data.SqlClient.SqlCommand scmd = new System.Data.SqlClient.SqlCommand(sqlString); scmd.Parameters.AddWithValue(“@ MesasgeText”,messageText); scmd.Parameters.AddWithValue(“@ SentDate”,DateTime.Now);

  2. 选择与编码/解码=>如果您将使用此选项不要忘记HtmlDecode当您将显示messageText到最终用户在网站上。

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

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

相关问题