#sql #delphi
#sql #delphi
Вопрос:
У меня есть веб-сервис со следующим кодом в реализации:
procedure Tferreteria.inserpersona(persona:Tpersona);
begin
//insertar persona
dm:=Tconsultas.Create(nil);
with dm.SQLQuery1 do
begin
Close;
SQL.Add('insert into persona (nombreyape, domicilio)values (:nombreyape,:domicilio);');
ParamByName('nombreyape').AsString:=persona.nombreyape;
ParamByName('domicilio').AsString:=persona.domicilio;
ExecSQL();
end;
end;
procedure Tferreteria.insercliente(cliente:Tcliente);
begin
//insertar cliente
with dm.SQLQuery1 do
begin
SQL.Clear;
SQL.Add ('insert into clientes(idcliente,idpersona,cuit,cuil) values (null,(select last_insert_id()),:cuit,:cuil);');
ParamByName('cuit').AsInteger:=cliente.cuit;
ParamByName('cuil').AsInteger:=cliente.cuil;
ExecSQL();
end;
end;
Как вы видите, это 2 процедуры, которые вставляют в таблицы personas и clientes. У клиентов есть столбец idpersona, который ссылается на персонажей
В событии нажатия кнопки у меня есть этот код
with Persona do
begin
nombreyape:=Form2.Edit1.Text;
domicilio:=Form2.Edit8.Text;
idlocalidad:=StrToInt(Form2.Edit3.Text);
end;
with Cliente do
begin
cuit:=StrToInt(Edit6.Text);
cuil:=StrToInt(Edit7.Text);
end;
//llamar al servicio
GetIferreteria.inserpersona(Persona);
GetIferreteria.insercliente(Cliente);
и я получаю эту ошибку
неверное целочисленное значение «aaa» для столбца cuit в строке 1,
когда в edit1 записывается aaa, который не назначен clientes.cuit,
Теперь у меня другая проблема:
Я должен вставить idpersona в clientes, но я должен вставить idpersona в telper, telper — это таблица, которая устанавливает связь между телефонами и людьми, у которых есть эти телефоны.
Если я сделаю то же самое с другим запросом, последним идентификатором вставки будет идентификатор из clientes (idcliente), а не idpersona.
Что я могу сделать, чтобы idpersona отображался для каждого момента, когда мне нужно его использовать, в каждой таблице, я имею в виду?
Комментарии:
1. Как вы можете надеяться на успех, не называя ничего. На самом деле вы не можете использовать Edit6 и т. Д. Конечно, нет.
2. Вам необходимо проверить входные данные перед отправкой их на ваш веб-сервис. Использование элемента управления TMaskEdit поможет предотвратить ошибки ввода конечным пользователем.
Ответ №1:
Я настоятельно рекомендую вам переписать этот код. Тем более, что вы используете last_insert_id()
(который вам не нужно select
восстанавливать), поэтому вы должны выполнить два оператора вместе, предпочтительно в транзакции (или, лучше, в хранимой процедуре).
Попробуйте что-то более похожее на это:
procedure Tferreteria.inserPersonaUnCliente(persona: Tpersona; cliente: Tcliente);
var
Query: TSQLQuery;
Conn: TSQLConnection;
SQL: TStrings;
Trans: TDBXTransaction;
begin
dm := Tconsultas.Create(nil);
Query := dm.SQLQuery1;
Conn := Query.SQLConnection;
SQL := Query.SQL;
//insertar persona un cliente
Query.Close;
Trans := Conn.BeginTransaction;
try
SQL.BeginUpdate;
try
SQL.Clear;
SQL.Add('insert into persona (nombreyape, domicilio) values (:nombreyape, :domicilio);';
SQL.Add('insert into clientes(idcliente, idpersona, cuit, cuil) values (null, last_insert_id(), :cuit, :cuil);');
finally
SQL.EndUpdate;
end;
Query.ParamByName('nombreyape').AsString := persona.nombreyape;
Query.ParamByName('domicilio').AsString := persona.domicilio;
Query.ParamByName('cuit').AsInteger := cliente.cuit;
Query.ParamByName('cuil').AsInteger := cliente.cuil;
Query.ExecSQL;
Conn.CommitFreeAndNil(Trans);
except
Conn.RollbackFreeAndNil(Trans);
raise;
end;
end;
with Persona do
begin
nombreyape := Form2.Edit1.Text;
domicilio := Form2.Edit8.Text;
idlocalidad := StrToInt(Form2.Edit3.Text);
end;
with Cliente do
begin
cuit := StrToInt(Edit6.Text);
cuil := StrToInt(Edit7.Text);
end;
//llamar al servicio
GetIferreteria.inserPersonaUnCliente(Persona, Cliente);
Комментарии:
1. Во втором операторе, в insert into clientes, говорится: «У вас ошибка в вашем sql sintax»… и в моей базе данных в таблице persona нет новой строки. Извините..
2. Если он жалуется на синтаксическую ошибку, он также должен сообщать вам, что на самом деле не так с синтаксисом. Единственное, что я изменил из синтаксиса вашего исходного оператора, это изменить
select last_insert_id()
на justlast_insert_id()
, поэтому попробуйте изменить это обратно.