我的查询是完美的(我已经在SQL Server管理工作室验证了它)。我的代码是完美的,我仍然得到这个语法错误:
'='附近语法错误。描述:在执行当前web请求期间发生了未处理的异常。请查看堆栈跟踪以获得有关错误及其在代码中的起源位置的更多信息。异常详细信息:System.Data.SqlClient.SqlException: '='附近语法不正确。
public partial class Temporaryche : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
ddlTDept.Items.Clear();
ddlTBranch.Items.Clear();
string connectionString = GlobalVariables.databasePath;
SqlConnection sqlCon = new SqlConnection(connectionString);
string query = "select fac.fac_name, dp.dp_name, br.br_name from STUDENT s, DIVISON dv, BRANCH br, DEPT dp, FACULTY fac, CLASS cls, DEGREE dg where dg.dg_id = cls.dg_id and cls.cls_id = s.cls_id and fac.fac_id = dp.fac_id and dp.dp_id = br.dp_id and br.br_id = dv.br_id and s.dv_id = dv.dv_id and s.prn_no = " + txtSearch.Text;
sqlCon.Open();
SqlCommand cmd = new SqlCommand(query, sqlCon);
SqlDataReader reader = cmd.ExecuteReader();
string facultyName = reader.GetValue(0).ToString();
string deptName = reader.GetValue(1).ToString();
string branchName = reader.GetValue(2).ToString();
ddlTFaculty.SelectedValue = facultyName;
query = "select dp_name from DEPT where fac_id=(select fac_id where fac_name='" + facultyName + "')";
cmd = new SqlCommand(query, sqlCon);
reader = cmd.ExecuteReader();
ddlTDept.Items.Clear();
while (reader.Read())
{
ddlTDept.Items.Add(reader.GetValue(0).ToString());
}
ddlTDept.SelectedValue = deptName;
sqlCon.Close();
}
}
您的代码中没有任何ExecuteNonQuery,因此唯一可能发生语法错误的地方是这一行
query = @"select dp_name from DEPT
where fac_id=(select fac_id where fac_name='" + facultyName + "')";
在这一行中,您错过了子查询中的FROM,因此您应该写为
query = @"select dp_name
from DEPT
where fac_id= (select fac_id
FROM DEPT where fac_name= '" + facultyName + "')";
当然,这只是解决您当前的问题,但正如其他人所说,您应该立即开始使用参数化查询。
例如query = @"SELECT dp_name FROM DEPT
wHERE fac_id = (SELECT TOP 1 fac_id
FROM DEPT
WHERE fac_name=@faculty";
cmd = new SqlCommand(query, sqlCon);
cmd.Parameters.Add("@faculty", SqlDbType.NVarChar).Value = facultyName;
....
编辑
我应该重写第一个表述。还有一个地方可能出现语法错误。如果txtSearch.Text
为空,则在第一行。
在这种情况下,查询仍然不完整,并触发语法错误。
这可能发生,因为在Page_Load
事件中调用代码时,文本框中仍然没有任何内容。所以,如果txtSearch
为空,我们应该添加一些东西来防止整个代码块的执行
protected void Page_Load(object sender, EventArgs e)
{
if(!string.IsNullOrWhiteSpace(txtSearch.Text))
{
.... code that executes the queries ...
}
}
总而言之,这段代码不适合Page_Load
事件,也许这段代码应该移动到一个按钮点击事件,当用户要求执行搜索....
最后,正如在注释中提到的,您应该使用JOIN语法来更好地将WHERE条件与表之间的关系分开。查询可以写成
SELECT fac.fac_name,
dp.dp_name,
br.br_name
FROM STUDENT s INNER JOIN DIVISION dv ON s.dv_id = dv.dv_id
INNER JOIN BRANCH br ON dv.br_id = br.br_id
INNER JOIN DEPT dp ON br.dp_id = dp.dp_id
INNER JOIN FACULTY fac ON dp.fac_id = fac.fac_id
INNER JOIN CLASS cls ON s.cls_id = cls.cls_id
INNER JOIN DEGREE dg ON cls.dg_id = dg.dg_id
WHERE s.prn_no=@search";
您没有提到发生错误的行,因此很难100%确定,还缺少其他一些信息。然而,在第一个SQL文本中,末尾有以下内容:
s.prn_no=" + txtSearch.Text;
因为是文本,所以应该用引号"
s.prn_no='" + txtSearch.Text +"'"
也就是说,由于SQl注入,你不应该像这样构建SQl查询。相反,您应该使用Parameter对象。