2013-09-04 3 views
1

Я использую базу данных MS Access, со следующими столбцами в таблице Admins:У меня есть ошибка синтаксиса в моих вставках в заявление

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; 

Я пробовал на день, чтобы понять, но с той же ошибкой, независимо от того, какой код я использую. Ошибка project1.exe поднял класс исключения

Проект eoleException с сообщением «Ошибка синтаксиса в заявлении INSERT INTO».

я также пытался:

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 повышает класс исключений eoleException с сообщением« ошибка в предложении FROM ».« – user2748631

+0

Я ожидаю, что проблема с тройными апострофами может быть проблемой. Возможно, вы можете использовать Double Quotes в качестве ваших литеральных разделителей или вам нужно, чтобы Escape Single Quotes правильно. Sontheim Solution должен использовать эквивалент delphi функции chr, представляющий одиночную цитату 'chr (39)'. – 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 заявление невозможно.)

Здесь вы должны внести некоторые изменения, которые очень важны для удобства обслуживания вашего кода.

Во-первых, немедленно нарушите привычку использовать имена по умолчанию для элементов управления, особенно те, которые вам нужно получить из вашего кода позже. Вы меняете имя, изменяя свойство Name для элемента управления в Инспекторе объектов.

В коде используется намного проще использовать NameEdit.Text, чем использовать Edit1.Text, особенно к тому времени, когда вы доберетесь до Edit14. Было бы намного яснее, если бы Edit14 было названо PasswordEdit, и вы будете счастливы, что через полгода вы изменили код.

Во-вторых, вам следует избегать использования преобразования по умолчанию из строки, которое происходит, когда вы используете ParamByName().Value. Он отлично работает, когда вы назначаете столбец text, но не очень хорошо, когда тип не является текстом (например, при использовании дат или цифр). В таких случаях перед выполнением задания необходимо преобразовать в соответствующий тип данных, чтобы вы были уверены, что все сделано правильно.

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

Наконец, вы должны никогда, никогда не использование конкатенации, таких как 'НЕКОТОРЫХ SQL ''' + Edit1.Text + '' ' '''. Это может привести к серьезной проблеме безопасности под названием SQL injection, которая может позволить злоумышленнику удалить ваши данные, сбросить таблицы или сбросить идентификаторы и пароли пользователей и предоставить им бесплатный доступ к вашим данным.Поиск Google найдет массу информации об уязвимостях, которые он может создать. Вы не должны даже делать это в коде, который, по вашему мнению, безопасен, потому что в будущем все может измениться, или вы можете получить недовольного сотрудника, который решает вызвать проблемы на выходе.

В качестве примера, если пользователь решает поставить John';DROP TABLE Admins; в edit14 в вашем приложении, и вы называете ExecSQL с этим SQL, вы больше не будете иметь Admins таблицу. Что произойдет, если вместо этого они вместо этого используют John';UPDATE Admins SET PASSWORD = NULL;? Теперь у вас нет пароля для любого из ваших администраторов.

+0

Только пользователи 10K и OP, конечно, полностью понимают, насколько вы терпеливы на этом. Выдающиеся усилия! – HansUp

+1

@HansUp: Спасибо. :-) Очень признателен. (Хотя, видимо, не этот плакат - см. [Следующий вопрос] (http://stackoverflow.com/q/18632222/62576), который игнорирует многое из того, что я написал здесь.) –

Смежные вопросы