字符串后面的”闭合引号附近的语法不正确’)’

我在Visual Web Dev 2010 Express中使用C#创建了一个Web表单,它包含文本框/标签(基于复选框)但是当我运行代码时运行SQL命令失败。 我在使用3个文本框之前已经使代码工作,但在扩展代码时似乎不起作用。

我尝试过的事情:

当谷歌搜索有人说一些关于引号是一个问题(并且错误反映了这一点),但如果我从SQL命令中删除所有引用它失败但我的想法是它总是必须是'"+datahere+"'是真的吗?

我还将在错误下面引用我所有的代码,以查找有问题的Web表单。 当我运行’debug’时,错误看起来像这样:

‘t’附近的语法不正确。 字符串’)’后面的未闭合引号。

描述:执行当前Web请求期间发生未处理的exception。 请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

exception详细信息:System.Data.SqlClient.SqlException:’t’附近的语法不正确。 字符串’)’后面的未闭合引号。

来源错误:

 Line 40: } Line 41: SqlCommand cmd = new SqlCommand("insert into sicknesstest values('"+txtname.Text+"','"+txtgrade.Text+"','"+txtdepot.Text+"','"+txtillness.Text+"','"+txtabsence.Text+"','"+txtcontactby.Text+"','"+txtupdate.Text+"','"+txtdetails.Text+"','"+txtresumedate.Text+"','"+txtdetail.Text+"','"+txtmedonreturn.Text+"','"+txtreporter.Text+"','"+txtdateofcontact.Text+"','"+txtresumeddate.Text+"')", con); Line 42: cmd.ExecuteNonQuery(); Line 43: con.Close(); Line 44: Label1.Visible = true; 

源文件:C:\ Users \ MYNAME \ Documents \ Visual Studio 2010 \ Projects \ SicknessDBNewSite \ SicknessDBNewSite \ WebForm2.aspx.cs行:42

堆栈跟踪:

 [SqlException (0x80131904): Incorrect syntax near 't'. Unclosed quotation mark after the character string ')'.] System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) +1791910 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) +5347106 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) +546 System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) +1693 System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout, Boolean asyncWrite) +869 System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite) +413 System.Data.SqlClient.SqlCommand.ExecuteNonQuery() +163 SicknessDBNewSite.WebForm2.Button1_Click(Object sender, EventArgs e) in C:\Users\MYNAME\Documents\Visual Studio 2010\Projects\SicknessDBNewSite\SicknessDBNewSite\WebForm2.aspx.cs:42 System.Web.UI.WebControls.Button.OnClick(EventArgs e) +9653178 System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +103 System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10 System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13 System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +35 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1724 

代码背后:webform2.aspx

        .style1 { width: 72%; } .style2 { width: 443px; } .style3 { text-align: center; text-decoration: underline; } .style4 { width: 443px; height: 65px; } .style5 { height: 65px; } .style6 { text-align: center; }    

Test Form Submission

Name
Grade
Depot
Nature of Illness?
Appointment made to see doctor (Yes or No)?
Medication Taken (Yes or No)?
Expected length of absence?
If not contacted by staff member, who contacted on their behalf?
Likely resumption date?
Contact telephone number
Latest update date
Details
Resumption Date
Detail
Is the person still on medication at the time of resumption?
Controller / Planner's name
Date of contact
Date and time of next shift
 
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="" SelectCommand="SELECT * FROM [sicknesstest]">

webform2.aspx.cs

  using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data.SqlClient; using System.Configuration; namespace SicknessDBNewSite { public partial class WebForm2 : System.Web.UI.Page { SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionStringTestFormSubmission"].ConnectionString); protected void Page_Load(object sender, EventArgs e) { con.Open(); } protected void Button1_Click(object sender, EventArgs e) { if (RadioAppointmentYes.Checked) { LabelAppointment.Text = "Yes"; } else if (RadioAppointmentNo.Checked) { LabelAppointment.Text = "No"; } if (RadioMedicationYes.Checked) { LabelAppointment.Text = "Yes"; } else if (RadioMedicationNo.Checked) { LabelAppointment.Text = "No"; } SqlCommand cmd = new SqlCommand("insert into sicknesstest values('"+txtname.Text+"','"+txtgrade.Text+"','"+txtdepot.Text+"','"+txtillness.Text+"','"+LabelAppointment.Text+"','"+LabelMedication.Text+"','"+txtabsence.Text+"','"+txtcontactby.Text+"','"+txtupdate.Text+"','"+txtdetails.Text+"','"+txtresumedate.Text+"','"+txtdetail.Text+"','"+txtmedonreturn.Text+"','"+txtreporter.Text+"','"+txtdateofcontact.Text+"','"+txtresumeddate.Text+"')", con); cmd.ExecuteNonQuery(); con.Close(); Label1.Visible = true; Label1.Text = "Your Data has been stored successfully! Click here to view"; txtname.Text = ""; txtgrade.Text = ""; txtdepot.Text = ""; txtillness.Text = ""; txtabsence.Text = ""; txtcontactby.Text = ""; txtupdate.Text = ""; txtdetails.Text = ""; txtresumedate.Text = ""; txtdetail.Text = ""; txtmedonreturn.Text = ""; txtreporter.Text = ""; txtdateofcontact.Text = ""; txtresumeddate.Text = ""; } } } 

– Datesource:

WebConfig:

数据库作为“测试托架”在我的机器上本地运行,并且我可以看到工作。

  

如果在尝试执行字符串之前输出字符串,则92.7% (a)的所有SQL执行问题都会变得明显。

你可能在输入字段的某个地方有一个流浪的引用,不一定是恶意的 – 它可能是由于oh no, we won't gocode doesn't workcontact Mr O'Rourke

这意味着做类似的事情:

 string strcmd = "insert into ..."; // Examine/output strcmd here. SqlCommand cmd = new SqlCommand(strcmd); cmd.ExecuteNonQuery(); 

然后,一旦你运行它,查找“SQL注入攻击”和“SQL预处理语句”这两个术语。 在某些时候,你会想要开始使用后者来防止前者。


(a)图中掏出空气, 实际值可能会有所不同:-)

我的建议是在查询中使用参数而不是连接。 在sql查询中使用参数的示例如下:

 IDbCommand command = conn.CreateCommand(); command.CommandText = "SELECT * FROM M_ITEM_SERIAL WHERE ITSR_PLANT_ID = @plantId"; IDbDataParameter plantIdParam = command.CreateParameter(); plantIdParam.ParameterName = "@plantId"; plantIdParam.Direction = ParameterDirection.Input; plantIdParam.Value = plantId; command.Parameters.Add(plantIdParam); 

尝试重建你的陈述。 在c#中,我永远不会像这样连接字符串,请使用String.Format 。 通常,由于SQL注入,您甚至不应该以这种方式将参数传递给数据库。 尝试使用SqlParameter

我认为您的问题是由于某些文本框中的值错误而发生的,当您使用SqlParameter时不会发生这种情况。

您应该阅读此SO-Answer: 使用ado.net通过C#将值插入SQL Server数据库