Делал для своего компонента TPSDBTreeView функцию “вырезать, копировать, вставить” на основе InsertSelect. Проблема в том, что если пытаться копировать все поля, скажем так
1 |
insert into users SELECT * FROM coffeetest_db.users; |
то получим
1 2 |
10:35:43 insert into users SELECT * FROM coffeetest_db.users Error Code: 1062. Duplicate entry '1025' for key 'PRIMARY' 0.016 sec |
Что же делать в таком случае? Нашёл такой выход
Вот пример из проекта
1 2 3 4 5 6 7 8 |
set @cols=(SELECT GROUP_CONCAT("`", COLUMN_NAME, "`") FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'users' and TABLE_SCHEMA = 'coffeetest_db' AND COLUMN_NAME NOT IN ('id')); set @query=CONCAT('insert into ','users' ,'(',@cols,')',' Select ',@cols,' FROM ','users',' where id=',1159); #select(@query); PREPARE stmt1 FROM @query; EXECUTE stmt1; |
При вставке в Delphi TFDQuery
1 2 3 4 5 6 7 |
set @cols=(SELECT GROUP_CONCAT("`", COLUMN_NAME, "`") FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = :tablename and TABLE_SCHEMA=:dbname AND COLUMN_NAME NOT IN ('id')); set @query=CONCAT('insert into ',:tablename ,'(',@cols,')',' Select ',@cols,' FROM ',:tablename,' where id=',:id); PREPARE stmt1 FROM @query; EXECUTE stmt1; |
Что происходит в коде? Мы просто составляем запрос на уровне базы, выкидывая ненужные колонки, в нашем случае id и исполняем его там.
И далее обращаться, скажем так
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
procedure TPSDBTreeViewSQL.SetInsertSelectSQLText2(AID: integer); var mc:TPSDBTreeViewMC; withoutQuotes: string; begin mc:=(Self.Owner as TPSDBTreeViewMC); withoutQuotes := StringReplace(mc.DBTable,'`','',[rfReplaceAll]); with qInsertSelect2 do begin Connection := mc.FDConnection; params.ParamValues['id'] := AID; params.ParamValues['tablename'] := withoutQuotes; end; end; |