我在C#项目中使用本地Access数据库。我需要开发一个复杂的SQL查询,但我有点卡住了。我的表结构是:
Student:
(PK)TagID StudentID (FK)CourseID
4855755 HUJ564334 25
4534664 RED231232 33
Course
(PK)CourseID CourseName
25 Computer Science
33 Biology
CourseID-ModuleID
(FK)CourseID (FK)ModuleID
25 CMP2343
25 CMP3456
33 BIO3422
33 BIO2217
Module
(PK)ModuleID ModuleName
CMP2343 Networking
CMP3456 Databases
BIO3422 Human body
BIO2217 Genetics
ModuleID-SessionID
(FK)ModuleID (FK)SessionID
CMP2343 1ACMP2343
CMP2343 2ACMP2343
CMP3456 1ACMP3456
CMP3456 2ACMP3456
BIO3422 1ABIO3422
BIO3422 2ABIO3422
BIO2217 1ABIO2217
BIO2217 2ABIO2217
Session
(PK)SessionID SessionDate SessionTimeStart SessionTimeEnd
1ACMP2343 09/05/2013 12:00 AM 14:00 PM
2ACMP2343 05/05/2013 09:00 AM 11:00 PM
1ACMP3456 15/05/2013 12:00 AM 13:00 PM
2ACMP3456 01/05/2013 10:00 AM 13:00 PM
1ABIO3422 30/04/2013 11:00 AM 13:00 PM
2ABIO3422 01/04/2013 14:00 AM 16:00 PM
1ABIO2217 12/05/2013 16:00 AM 18:00 PM
2ABIO2217 03/05/2013 12:00 AM 14:00 PM
Attendance
(FK)TagID (FK)SessionID ScanningTime
我希望我的查询找到给定TagID的“当前”SessionID(通过查找会话的日期和时间,保存在DB中),并在Attendance表中显示TagID和SessionID,以及时间扫描。
我使用以下方法设置与DB的连接,并在dataGridView2中显示数据:
public void setSQL()
{
string ConnStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\jasper\\Desktop\\AutoReg\\AutoReg\\AutoReg.accdb;";
OleDbConnection MyConn = new OleDbConnection(ConnStr);
MyConn.Open();
DataSet ds = new DataSet();
//query to ask
string query = @"SELECT s.TagID, se.SessionID, " + "'" +
DateTime.Now.ToString("MM/dd/yy HH:mm:ss tt") + @"' AS scanningTime
FROM Student s,
CourseID-ModuleID cm,
ModuleID-SessionID ms,
Session se
WHERE 1=1
AND s.TagID = 4820427
AND s.CourseID = cm.CourseID
AND ms.ModuleID = cm.ModuleID
AND ms.SessionID = se.SessionID
AND se.SessionDate = Date();";
OleDbCommand command = new OleDbCommand(query, MyConn);
OleDbDataAdapter adapter = new OleDbDataAdapter(command);
adapter.Fill(ds);
dataGridView2.DataSource = ds.Tables[0];
MyConn.Close();
}
当我执行上面的代码时,出现错误:
An unhandled exception of type 'System.Data.OleDb.OleDbException' occurred in System.Data.dll
Additional information: IErrorInfo.GetDescription failed with E_FAIL(0x80004005).
我确信方法结构没问题,因为我可以运行并显示一个简单的查询,例如:"SELECT * FROM Student";
答案 0 :(得分:0)
我设法让这个查询有效。我已经解决了它在表名周围添加方括号。首先,SESSION字是ms-access jet SQL中的保留关键字,因此您需要将该名称封装在方括号中。然而,奇怪的是你需要在CourseID-ModuleID
和ModuleID-SessionID
表周围添加方括号。 MS-Access-OleDb引擎不能很好地接受减号字符,如果你尝试一个简单的"SELECT * FROM CourseID-ModuleID"
,你会得到一个语法错误,如果你把方括号放在表名周围就会消失
string query = @"SELECT s.TagID, se.SessionID, '" +
DateTime.Now.ToString("MM/dd/yy HH:mm:ss tt") +
"' AS scanningTime " +
"FROM (((Student s " +
" LEFT JOIN [CourseID-ModuleID] cm ON s.CourseID = cm.CourseID) " +
" LEFT JOIN [ModuleID-SessionID] ms ON ms.ModuleID = cm.ModuleID) " +
" LEFT JOIN [Session] se ON ms.SessionID = se.SessionID) " +
"WHERE s.TagID = 4820427 AND se.SessionDate = Date()";
使用Access界面,方括号会自动添加到查询文本中,因此错误不会立即显示。
作为旁注,se.SessionData = Date()
有效删除任何结果,因为没有SessionDate等于当前日期。