2013-09-04 1 views
1
나는 Admins 테이블에 다음과 같은 열 더불어, MS Access 데이터베이스를 사용하고

에 내 삽입에 구문 오류가 : 이것은 내 코드입니다나는 문

Column  Type 
======  ==== 
Name   Text 
Surname  Text 
Dateadded  Date/time 
Adminnumber Number(long integer) 
Password  Text 
ID type  Autonumber (Not sure if ID is relevant) 

그러나 그것은 나에게 구문 오류를주는 유지 .

ADOquery1.Active := false; 
adoquery1.sql.Text := 'insert into Admins(Name, surname, Adminnumber, Dateadded,password)Values('''+edit11.Text+''', '''+edit12.text+''', '''+edit13.Text+''', '''+edit14.Text+''', '''+edit15.text+''')'; 
ADOquery1.ExecSQL; 
Adoquery1.SQL.Text := 'select * from Admins'; 
ADOquery1.Active := true; 

나는 하루를 알아 내려고 노력했지만 그 코드는 내가 사용하는 코드에 상관없이 동일한 오류가 발생했습니다. 오류 메시지 'INSERT INTO 문의 구문 오류'로

프로젝트 만들기 Project1.exe 발생한 예외 클래스 eoleException 입니다.

나는 또한 시도 :

ADOquery1.SQL.Add('Insert into admins'); 
ADOquery1.SQL.Add('(Name , Surname, Dateadded, Adminnumber, Password)'); 
ADOquery1.SQL.Add('Values :Name, :Surname, :Dateadded, :adminnumber :Password)'); 
ADOquery1.Parameters.ParamByName('Name').Value := edit11.Text; 
ADOquery1.Parameters.ParamByName('Surname').Value := edit12.Text; 
ADOquery1.Parameters.ParamByName('Dateadded').Value := edit13.Text; 
ADOquery1.Parameters.ParamByName('Password').Value := edit14.Text; 
ADOquery1.Parameters.ParamByName('Adminnumber').Value := edit15.Text; 
ADOquery1.ExecSQL; 
ADOquery1.SQL.Text := 'Select * from admins'; 
ADOquery1.Open ; 

하지만이 코드는 절

에서 저에게 문제를 제공
+1

정확한 오류 란 무엇인가요? 오류를 생성하는 쿼리의 정확한 텍스트는 무엇입니까? 첫 번째 버전은 사용자가 원하는 모든 SQL을 실행할 수 있으므로 여러 가지 구문 오류가 발생할 수 있습니다. (힌트 : SQL 주입 공격에 대해 광범위하게 열려 있습니다.) – David

+0

첫 번째 코드의 정확한 오류는 "project project1.exe에서 예외 클래스 eoleException이 발생했습니다. 'INSERT INTO 문에서 구문 오류가 발생했습니다.' 그리고 두 번째 코드 오류는 "project project1.exe가 'FROM clause'오류 메시지와 함께 예외 클래스 eoleException을 발생 시켰습니다." – user2748631

+0

트리플 아포스트로피가 문제가 될 것으로 기대하고 있습니다. 리터럴 구분 기호로 큰 따옴표를 사용하거나 Sontheim Solution은 'chr (39)'에 의해 작은 따옴표를 나타내는'chr' 함수와 동일한 델파이의 함수를 사용합니다 : – collapsar

답변

9

문제는 Name (그리고 아마도 Password)는 MS Access에서 예약어이다 . 열 이름에 대해서는 좋지 않은 선택이지만, 사용해야하는 경우 대괄호 ([])로 묶어서 열어야합니다. VALUES 문 뒤에 여는 괄호 (()가없고 :adminnumber 매개 변수 다음에 쉼표가 없습니다.

ADOquery1.SQL.Add('Insert into admins'); 
ADOquery1.SQL.Add('([Name] , [Surname], [Dateadded], [Adminnumber], [Password])'); 
ADOquery1.SQL.Add('Values (:Name, :Surname, :Dateadded, :adminnumber, :Password)'); 
ADOquery1.Parameters.ParamByName('Name').Value := edit11.Text; 
ADOquery1.Parameters.ParamByName('Surname').Value := edit12.Text; 
ADOquery1.Parameters.ParamByName('Dateadded').Value := edit13.Text; 
ADOquery1.Parameters.ParamByName('Password').Value := edit14.Text; 
ADOquery1.Parameters.ParamByName('Adminnumber').Value := edit15.Text; 
ADOquery1.ExecSQL; 
ADOquery1.SQL.Text := 'Select * from admins'; 
ADOquery1.Open; 

는 (이 오류는 당신은 당신의 질문에 대한 코멘트에 말한대로, 주변에 이동 할 수 없습니다. 아마도 문제가 발생할 수있는 유일한 라인은 ADOQuery1.ExecSQL; 라인, 그것은 INSERT을 실행하는 유일한 사람으로 다른 라인에서 예외를 발생시키는 것은 불가능합니다.)

코드의 유지 보수성에 매우 중요한 몇 가지 사항을 변경해야합니다.

먼저 컨트롤의 기본 이름, 특히 코드에서 나중에 액세스해야하는 컨트롤의 기본 이름을 사용하는 습관을 즉시 해제하십시오. Object Inspector에서 컨트롤의 Name 속성을 변경하여 이름을 변경합니다.

Edit14에 도착할 때까지 NameEdit.Text을 사용하는 것이 코드 Edit1.Text을 사용하는 것보다 훨씬 쉽습니다. Edit14의 이름이 PasswordEdit 인 경우 훨씬 명확해질 수 있으며 코드를 변경해야하는 시점부터 6 개월 후에 도움이됩니다.

두 번째로 ParamByName().Value을 사용할 때 발생하는 문자열의 기본 변형을 사용하지 마십시오. text 열에 할당 할 때 제대로 작동하지만 형식이 텍스트가 아닌 경우 (날짜 또는 숫자를 사용할 때와 같이) 좋지 않습니다. 이러한 경우 할당을 수행하기 전에 올바른 데이터 유형으로 변환해야 올바르게 완료되었는지 확인할 수 있습니다.

ADOQuery1.ParamByName('DateAdded').Value := StrToDate(DateEdit.Text); 
ADOQuery1.ParamByName('AdminNumber').Value := StrToInt(AdminNum.Text); 

마지막으로해야 결코 같은 '일부 SQL' ''+ Edit1.Text + '' ',' ''변함 사용 문자열 연결. 이로 인해 악의적 인 사용자가 데이터를 삭제하거나 테이블을 삭제하거나 사용자 ID와 암호를 다시 설정하고 데이터에 자유롭게 액세스 할 수있는 SQL injection이라는 심각한 보안 문제가 발생할 수 있습니다.Google 검색은 만들 수있는 취약점에 대한 수많은 정보를 찾습니다. 미래에 상황이 바뀔 수 있거나 문제가 발생하기로 결정한 불만을 품은 직원을 얻을 수 있기 때문에 안전하다고 생각되는 코드로 작업하지 않아야합니다. 사용자가 응용 프로그램에서 edit14John';DROP TABLE Admins;를 넣어하기로 결정하고, 해당 SQL에 ExecSQL를 호출하는 경우

는 예를 들어, 당신은 더 이상 Admins 테이블이 없습니다. 대신에 John';UPDATE Admins SET PASSWORD = NULL;을 대신 사용하면 어떻게됩니까? 이제 관리자 사용자에게는 암호가 없습니다.

+0

오직 10K 명의 사용자와 OP만이 당신이이 환자에 얼마나 참을성이 있었는지 완전히 이해합니다. 탁월한 노력! – HansUp

+1

@HansUp : 감사합니다. :-) 매우 감사. (분명히이 포스터가 아니더라도 - 내가 다음에 쓴 것을 많이 무시한 [다음 질문] (http://stackoverflow.com/q/18632222/62576)을 참조하십시오.) –