문제
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 명령 텍스트를 검사하고 그에 따라 행동하면됩니다.