문제

DAO를 사용하여 액세스 데이터베이스에 대해 쿼리 목록을 실행하고 싶습니다. "database.execute ()"메소드는 "action queries"만 실행할 수 있다는 비고와 함께 이에 맞는 것으로 보입니다. 이는 결과 세트를 반환하지 않는 쿼리입니다 (MSDN 참조). 레코드를 반환하는 쿼리의 경우 "database.openrecordset ()"를 사용할 수 있습니다. 잘못된 유형의 쿼리가 전달되면 두 방법 모두 예외를 던집니다.

목록에 액션 쿼리와 쿼리를 선택하면 레코드를 반환 할 수있는 선불 결정 방법과 그렇지 않은 선행을 어떻게 결정할 수 있습니까?

도움이 되었습니까?

해결책 3

@Hansup의 답변에서 영감을 얻은 DAO 인터페이스가 제공하는 QueryDef 구조를 좀 더 조사했습니다. 구조에는 다른 쿼리 유형을 구별하는 데 사용할 수있는 "유형"속성이 있습니다.MSDN). 다음과 같은 구현으로 끝났습니다.

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;

도움이되는 답변과 발언에 감사드립니다.

다른 팁

ADO 실행 방법은 쿼리가 결과 세트를 반환하는지 여부에 관계없이 사용할 수 있습니다.

그러나 당신은 정말로 모든 '쿼리'를 실행하고 싶습니까? SQL DDL을 포함하면 어떻게됩니까? 당신이 만든 것을 고려하십시오 PROCEDURE 이 SQL DDL 코드 사용 :

CREATE PROCEDURE qryDropMe AS DROP PROCEDURE qryDropMe;

;)

액세스는 쿼리 유형을 나타내는 값을 저장하는 필드 (플래그)를 포함하는 MSYSOBJECTS라는 숨겨진 시스템 테이블을 유지 관리합니다. 목록에서 각 쿼리 이름으로 다음 기능을 시도하고 리턴 값을 사용하여 Database.Execute () 또는 Database.OpenRecordset ()를 사용할지 여부를 결정할 수 있습니다.

이 함수는 msysobjects에 대한 읽기 권한이 필요합니다. 일부 액세스 2007 사용자가 MSYSOBJECTS를 읽을 수있는 권한이 거부 된 것보다 보고서를 들었습니다. 그러나 Access 2007에서 그 문제를 발견하지 못했습니다.

플래그 값을 결정하기 위해 몇 가지 쿼리 유형을 테스트했습니다. 쿼리 중 하나가 테스트하지 않은 유형 인 경우 함수는 인식 할 수없는 것으로 플래그 값을 반환합니다. 해당 플래그 유형을 포함하도록 함수를 수정할 수 있습니다.

내가 테스트 한 유일한 DDL 쿼리는 드롭 테이블 (flags = 96)이었습니다.

또한 모든 "Select ... From ..."쿼리가 귀하의 목적을위한 선택 쿼리 (레코드 세트 반환)가 아닙니다. "Select 필드 OldTable의 Newtable에; ""레코드를 반환하지 않으며 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

예외를 잡아서 분석하지 않는 이유는 무엇입니까?

시작 트랜스/롤백 명령을 사용하는 방법이 있습니까? 그런 다음 SQL 명령을 보내고 오류를 수집 한 다음 거래를 롤백하여 데이터베이스를 변경하지 않은 상태로 유지할 수 있습니다.

ADO 연결을 사용하는 것은 어떨까요, ADO One보다 다소 똑똑한 것은 무엇입니까? 여기서 연결은 '오류'수집을 유지하고 영향을받는 레코드 수와 같은 다른 데이터를 반환합니다.

이 정보는 쿼리 유형에 적용됩니다. 그래서:

  • 실행하는 모든 쿼리 a 선택 ... ~이다 쿼리를 선택하십시오
  • 모두 끼워 넣다, 업데이트, 삭제 ~이다 조치 쿼리

위의 키워드 중 하나부터 시작하는 경우 쿼리 SQL 명령 텍스트를 검사하고 그에 따라 행동하면됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top