如何在select查询中给出where条件?

时间:2009-07-02 11:38:47

标签: ms-access types jet-sql

如何在select查询中给出where条件?

ACCESS 2003

我的查询

SELECT RECORDNO, PERSONID, EMPNAME, TITLENAME, DEPARTMENT, NATION, 
CARDEVENTDATE, INTIME, OUTTIME, (select TOP 1 F1.CARDEVENTDATE from 
tmp_cardevent as F1 where F1.RECORDNO < F2.RECORDNO AND F1.PERSONID = 
F2.PERSONID order by F1.RECORDNO DESC, F1.PERSONID DESC) AS PrevDate, 
(select TOP 1 F1.OUTTIME from tmp_cardevent as F1 where F1.RECORDNO < 
F2.RECORDNO AND F1.PERSONID = F2.PERSONID order by F1.RECORDNO DESC, 
F1.PERSONID DESC) AS PrevOut FROM tmp_cardevent AS F2 

我想用:

WHERE CARDEVENTDATE BETWEEN '" & sdate & "' AND '" & edate & "'

从上面的查询我怎么能​​给出where条件,我试过这个:

SELECT RECORDNO, PERSONID, EMPNAME, TITLENAME, DEPARTMENT, NATION, 
CARDEVENTDATE, INTIME, OUTTIME, (select TOP 1 F1.CARDEVENTDATE from 
tmp_cardevent as F1 where F1.RECORDNO < F2.RECORDNO AND F1.PERSONID = 
F2.PERSONID order by F1.RECORDNO DESC, F1.PERSONID DESC) AS PrevDate, 
(select TOP 1 F1.OUTTIME from tmp_cardevent as F1 where F1.RECORDNO < 
F2.RECORDNO AND F1.PERSONID = F2.PERSONID order by F1.RECORDNO DESC, 
F1.PERSONID DESC) AS PrevOut FROM tmp_cardevent AS F2
WHERE F2.CARDEVENTDATE BETWEEN '" & sdate & "' AND '" & edate & "' 

但显示“DATA TYPE MISMATCH ERROR”

我也尝试过:

 SELECT RECORDNO, PERSONID, EMPNAME, TITLENAME, DEPARTMENT, NATION, 
CARDEVENTDATE, INTIME, OUTTIME, (select TOP 1 F1.CARDEVENTDATE from 
tmp_cardevent as F1 where F1.RECORDNO < F2.RECORDNO AND F1.PERSONID = 
F2.PERSONID and F2.CARDEVENTDATE BETWEEN '" & sdate & "' AND '" & edate 
& "' order by F1.RECORDNO DESC, F1.PERSONID DESC) AS PrevDate, (select 
TOP 1 F1.OUTTIME from tmp_cardevent as F1 where F1.RECORDNO < 
F2.RECORDNO AND F1.PERSONID = F2.PERSONID order by F1.RECORDNO DESC, 
F1.PERSONID DESC) AS PrevOut FROM tmp_cardevent AS F2 WHERE 
F2.CARDEVENTDATE BETWEEN '" & sdate & "' AND '" & edate & "' 

但它显示相同的“数据类型错误错误”

任何人都可以帮助我

2 个答案:

答案 0 :(得分:5)

Access使用#作为日期文字的分隔符,而不是'。你需要相应地更换。

答案 1 :(得分:0)

不要将文字字符串喷射到SQL文本中,而应考虑使用预准备语句。这不仅可以为您提供SQL注入保护,还可以将参数值的创建推迟到您选择的数据访问库,例如:以下ADO代码使用Access数据库引擎的专用OLE DB提供程序创建DATETIME值,使用VBA函数CDate()使用本地计算机上的Windows区域设置将表示日期的字符串转换为Date值(当然,这可能与具有数据库文件的机器不同):

Dim sDate As String
sDate = 4/1/09"  ' ambiguous DATETIME value

Dim eDate As String
eDate = "2009-12-31 23:59:59"  ' unambiguous DATETIME value

Dim cmd As ADODB.Command
Set cmd = New ADODB.Command
With cmd
  .ActiveConnection = CurrentProject.Connection  ' Access UI object
  .CommandText = _
      "SELECT * " & _
      "  FROM Cards " & _
      " WHERE CARDEVENTDATE BETWEEN :start_date AND :end_date;"
  .Parameters.Append .CreateParameter( _
      ":start_date", adDate, adParamInput, , CDate(sDate))
  .Parameters.Append .CreateParameter( _
      ":end_date", adDate, adParamInput, , CDate(eDate))

  Dim rs As ADODB.Recordset
  Set rs = .Execute
End With

MsgBox rs.GetString

更好的是,将其设为存储过程,例如在设计时这样做一次:

CurrentProject.Connection.Execute _
  "CREATE PROCEDURE GetCards " & _ 
  "( " & _ 
  " :start_date DATETIME, " & _ 
  " :end_date DATETIME " & _ 
  ") " & _ 
  "AS " & _ 
  "SELECT * " & _ 
  "  FROM Cards " & _ 
  " WHERE CARDEVENTDATE BETWEEN :start_date AND :end_date;"

然后在运行时每次都使用它:

.CommandText = _
  "EXECUTE GetCards :start_date, :end_date;"

这样一来,如果你的查询需要改变(但是所需的参数不需要 - 你总是可以附加带有默认值的可选参数),你可以只更改一个后端的proc而不必更改SQL所有前端的代码。