Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 使用DAO执行查询_Delphi_Ms Access_Dao - Fatal编程技术网

Delphi 使用DAO执行查询

Delphi 使用DAO执行查询,delphi,ms-access,dao,Delphi,Ms Access,Dao,我想使用DAO对Access数据库执行一系列查询。“Database.Execute()”方法似乎适合这种情况,并指出它只能执行“操作查询”,即不返回结果集()的查询。对于返回记录的查询,可以使用“Database.OpenRecordset()”。如果传递了错误类型的查询,这两种方法都会引发异常 在列表中既有操作查询又有选择查询,如何预先决定哪些将返回记录,哪些不返回记录?此信息适用于查询类型。因此: 执行SELECT命令的所有查询。。。从…起是选择查询 所有插入、更新和删除都是操作查询

我想使用DAO对Access数据库执行一系列查询。“Database.Execute()”方法似乎适合这种情况,并指出它只能执行“操作查询”,即不返回结果集()的查询。对于返回记录的查询,可以使用“Database.OpenRecordset()”。如果传递了错误类型的查询,这两种方法都会引发异常


在列表中既有操作查询又有选择查询,如何预先决定哪些将返回记录,哪些不返回记录?

此信息适用于查询类型。因此:


  • 执行SELECT命令的所有查询。。。从…起是选择查询
  • 所有插入、更新和删除都是操作查询

您只需检查查询sql命令文本,查看它是否以上述任何关键字开头,并相应地执行操作。

请注意,无论查询是否返回结果集,都可以使用ADO Execute方法

但是你真的想执行所有的“查询”吗?如果它们包含SQLDDL呢?考虑使用这个SQL DDL代码创建<代码>过程<代码>:< /p>
CREATE PROCEDURE qryDropMe AS DROP PROCEDURE qryDropMe;

)()

Access维护一个名为MSysObjects的隐藏系统表,其中包含一个字段(标志),该字段存储一个指示查询类型的值。您可以使用列表中的每个查询名称尝试以下函数,并使用返回值确定是使用Database.Execute()还是Database.OpenRecordset()

该函数要求MSysObjects具有读取权限。我听说一些Access 2007用户被拒绝读取MSysObjects的报告。但是,我在Access 2007中没有遇到这个问题

我测试了几种查询类型以确定标志值。如果您的查询之一是我没有测试的类型,则函数将返回无法识别的标志值。您可以修改该函数以包含该标志类型

我测试的唯一DDL查询是DROP TABLE(Flags=96)

另外,请注意,并非所有“选择…从…”查询都是出于您的目的而进行的选择查询(返回记录集)。诸如“从旧表中将字段选择为新表”之类的查询不会返回记录,Access UI将其分类为生成表查询

Public Function QueryType(ByVal pQueryName As String) As String
    Dim lngFlags As Long
    Dim strType As String
    Dim strCriteria As String

    strCriteria = "[Name] = """ & pQueryName & """ And [Type] = 5"
    lngFlags = DLookup("Flags", "MSysObjects", strCriteria)

    Select Case lngFlags
    Case 0
        strType = "Select"
    Case 16
        strType = "Crosstab"
    Case 32
        strType = "Delete"
    Case 48
        strType = "Update"
    Case 64
        strType = "Append"
    Case 80
        strType = "Make Table"
    Case 96
        strType = "Drop Table"
    Case 128
        strType = "Union"
    Case Else
        strType = "Flags " & CStr(lngFlags) & " unrecognized"
    End Select

    QueryType = strType
End Function

为什么不捕获抛出的异常并对其进行分析

您有没有办法使用beginTrans/Rollback指令?然后可以发送SQL命令,收集错误,然后回滚事务,保持数据库不变


使用ADO连接怎么样?ADO连接比ADO连接稍微聪明一些,其中连接保存一个“错误”集合并返回一些其他数据,如受影响的记录数?

受@HansUp回答的启发,我进一步研究了DAO接口提供的QueryDef结构。该结构有一个“Type”属性,我可以使用它来区分不同的查询类型()。我最终实现了以下功能:

function TAccessDatabase.SQLExec(AName, AQuery: String): Integer;
var
  I: Integer;
  QDef: QueryDef;
  QDefExists: Boolean;
begin
  Result := 0;

  // Lookup querydef in the database
  QDefExists := False;
  for I := 0 to DB.QueryDefs.Count - 1 do
  begin
    QDef := DB.QueryDefs[I];
    if QDef.Name = AName then
    begin
      QDefExists := True;
      break; //-->
    end;
  end;

  // Create query def if it doesn't exists
  if not QDefExists then
  begin
    QDef := DB.CreateQueryDef(AName, AQuery);
    // Refresh is required to get the correct QDef.Type_
    DB.QueryDefs.Refresh;
  end;

  // Execute the query only if it is not a SELECT
  if QDef.Type_ <> dbQSelect then
  begin
    db.Execute(AQuery, dbInconsistent);
    Result := DB.RecordsAffected;
  end;
end;
函数TAccessDatabase.SQLExec(AName,AQuery:String):整数;
变量
I:整数;
QDef:QueryDef;
qdef存在:布尔;
开始
结果:=0;
//在数据库中查找querydef
QDefExists:=False;
对于I:=0到DB.querydfs.Count-1 do
开始
QDef:=DB.querydfs[I];
如果QDef.Name=AName,则
开始
QDefExists:=真;
中断;//-->
结束;
结束;
//如果查询定义不存在,则创建查询定义
如果不存在,那么
开始
QDef:=DB.CreateQueryDef(AName,AQuery);
//需要刷新才能获得正确的QDef.Type_
DB.querydfs.Refresh;
结束;
//仅当查询不是SELECT时才执行该查询
如果QDef.Type uqselect,则
开始
db.Execute(AQuery,dbunconsistent);
结果:=DB.RecordsAffected;
结束;
结束;

谢谢所有有用的答案和备注。

“执行SELECT……的所有查询都是SELECT查询”——但它们不返回结果集,例如考虑“查询”是否包含SQLDDL“创建视图MyView为客户选择客户机ID”;这不是选择查询,而是创建查询,不会给出任何结果。。。这一个属于“操作查询”类别,与所有DDL查询一样。那么回到原始问题:“我如何预先决定哪些将返回记录,哪些将不返回记录?”换句话说,您如何判断包含SELECT关键字的查询是否将返回结果集?插入到..选择。。是另一个示例构造。这个构造也不会返回任何结果集,因为它基本上是一个插入。引用我的回答:“…检查查询sql命令文本,看看它是否以上述任何关键字开头…”根据需要,可以随意向这两个组添加一些其他关键字(如DDL语句CREATE、DROP…)嗯,那么以PARAMETERS关键字开头,后跟SELECT关键字的查询呢?一个以SELECT关键字开头,然后使用到[NewTableName]中,因此不返回结果集的如何?谢谢你的提议,但我觉得我无法编辑你的答案来改进它;相反,它从根本上是有缺陷的,解析SQL无论如何都不是小事。我认为你这里没有一个可行的系统。从逻辑上讲,更新就是删除和插入。以上内容表明,对于Access数据库引擎,更新是删除和交叉表!有一天。不更新记录中所有字段的更新怎么会是逻辑删除和插入?@oneday-我想你在没有的地方读到了更具意义的内容-标志列表就是一个flags@DJ:根据我的经验,名为“flags”的枚举建议使用位掩码,更不用说值(16、32、64…)@Tony Toews:因为它使用未提及的列的现有值,并且一次发生。您是否在更新触发器上使用过SQL Server?您将有两个名为“inserted”和“deleted”的逻辑表,而不是一个名为“updated”的逻辑表。为什么您甚至要执行仅选择的查询,除非您