InsertSQL

11 отговора 0 прегледа
#1

InsertSQL

Привет на всички,
защо би могло да се случва следното:

поставям във форма едно DBISAMUpdateSQL и там на InsertSQL имам

INSERT INTO табле1 (поле1, поле2, поле3, .... полеЕН)
SELECT поле1, поле2, поле3, .... полеЕН
FROM табле2

слагам един бутон, който на клик да прави
NewUpdateSQL.ExecSQL(ukInsert);

И когато го кликам бутона, казва "DBISAM error #11010 table or backup TABLE2 does not exist"
Правих repair, verify на таблицата, на ново я създавах и все същото .....

Има ли друго осен ExecSQL, което се прави за да се изпълни SQLa?

---
(на)здраве и късмет
Отговор
в отговор на kalinkina #2

Re: InsertSQL

Така като гледам, повечето хора не са работили с това чудо DBISAM.
Така че най- добре [линк]
Освен това е платено, така че тяхната поддръжка трябва да помогне.

Отговор
в отговор на kalinkina #3

Re: InsertSQL

Открих го с проба-грешка :)
Оказа се, че на табле1 и табле2 трябва да му кажа физически къде се намират "С:\еди_къде_си\табле1 ......"

Отговор
в отговор на vido #4

какъв по-елегантен начин има

Пак съм аз с този InsertSQL .....


Имам едно множество (Таблица-А) и подмножество(Таблица-Б), трябва да получа разликата
Правя Query1 за да получа всички записи от Б, съдържащи се в А по поле-Х
Правя Query2 за да получа всички записи от Б, но не се съдържат в А по поле-Х
Възможно е да има дублирани записи и Query1 връща по-малко записи
За да ги намеря правя таблици от Query1 и Query2 (там слагам флаг ('1' ако е от табл1, '0' ако е от табл2)
после ще обединя табле1 и табле2 (резултата ще е равен на Табле-А) и после ще сетвам флага ръчно

with DataModule1.Query1 do
begin
Active:=false;
Active:=true;
SaveToTable('алабала','табле1');
end;
with DataModule1.Query2 do
begin
Active:=false;
Active:=true;
SaveToTable('алабала','табле2');
end;

INSERT INTO "алабала\табле1" (поле1,поле2,поле3)
SELECT поле1,поле2,поле3
FROM "алабала\табле2"

Получавам грешка "Update failed "

Предполагам този SaveToTable ми обърква нещата, защото имам поле, което е AutoIncrement в Таблица-А и Таблица-Б .....
Или след SaveToTable таблицата ми остава в заключен режим ?!?!

........ Нещо бъркам и не ми е ясно къде
Може ли някой да ми даде идея как да стигна до НовТабл=ТаблеА-ТаблеБ, така че и дублираните записи да са там .....

Отговор
в отговор на kaлиkинa #5

Re: какъв по-елегантен начин има

select field1, field2, field3 from table1
MINUS
select field1, field2, field3 from table2

но това може и да не работи на този специфичен DB сървар. Друг е въпроса че не разбрах какво точно искаш. Това връща всички записи от таблица1 които ги няма в таблица2. Записите които ги има и в двете таблици няма да са в резултата. Нещо не се вързва с "...така че и дублираните записи да са там ....."

Отговор
в отговор на vido #6

Re: какъв по-елегантен начин има

Всъщност точно това искам - да връща всички записи от таблица1 които ги няма в таблица2
Понеже понякога има дублиране на записи, моите quey-та не ги взимат под внимание и затова прибегнах към цялата гимнстика ;)

Май това с "MINUS"-а наистина го няма в ДБИСАМа ..... ще прочета повече, може да има друг метод

Отговор
в отговор на kalinkina #7

Re: какъв по-елегантен начин има

Може да използваш такова query, което да ти върне разликата (но трябва да нямаш nulls във t2.field1):

select t1.field1, t1.field2, t1.field3
from t1
left join t2 on (t1.field1 = t2.field1 and t1.field2 = t2.field2 and t1.field3 = t2.field3)
where t2.field1 is null

Редактирано от Formal на

Отговор
в отговор на Formal #8

Re: какъв по-елегантен начин има

Аз точно това съм направила, но резултата не винаги е реален, заради дублиращи суми

SELECT NwS.id, NwS.idstat, NwS.StDate, NwS.pay, NwS.ibancust, NwS.line
FROM NwS LEFT JOIN NwA ON (NwS.ibancust = NwA.ibancust) AND (NwS.pay = NwA.pay)
WHERE (((NwA.pay) Is Null) AND ((NwA.ibancust) Is Null));

после добавям едно поле, в което сетвам флаг в '1' и правя временна
таблица и пускам още едно query с инверт на условието
WHERE (((NwA.pay) Is Null) AND ((NwA.ibancust) Is Not Null));
от което правя друга временна таблица със сетнат флаг '0' на всеки запис
Искам да ги залепя двете таблици (резултата ще е същия като ТаблицаА, но
със флагове на всеки рекорд) и после ръчно ще сетвам записите, които
първото query не е прихванало .........

но нещо не ми върви InsertSQL-a

Отговор
в отговор на Formal #9

НАМЕРИХ РЕШЕНИЕТО

Ееееей, голяма съм калинка! Знаех си, че ще излезе нещо елементарно!!!!!

Та порових в DBISAMa и намерих аналога на MINUS, казвa се EXCEPT
Но в крайна сметка след като създам временните таблици употребих UNION
и така ги залепих резултатите от двете query-taaaaaa

Отговор
в отговор на kalinkina #10

Re: какъв по-елегантен начин има

Нещо пак не разбрах, ето един експеримент:

create table __at1 (id int, f1 int, f2 int)
create table __at2 (id int, f1 int, f2 int)
insert into __at1 values (1, 1, 1)
insert into __at1 values (2, 1, 2)
insert into __at1 values (3, 1, 3)
insert into __at1 values (4, 2, 1)
insert into __at1 values (5, 2, 2)
insert into __at1 values (6, 2, 3)
insert into __at1 values (7, 3, 1)
insert into __at1 values (8, 3, 2)
insert into __at1 values (9, 3, 3)

insert into __at2 values (11, 1, 1)
insert into __at2 values (12, 1, 2)
insert into __at2 values (13, 1, 4)
insert into __at2 values (14, 2, 1)
insert into __at2 values (15, 2, 2)
insert into __at2 values (16, 2, 4)
insert into __at2 values (17, 4, 1)
insert into __at2 values (18, 4, 2)
insert into __at2 values (19, 4, 4)

select __at1.id, __at1.f1, __at1.f2
from __at1
left join __at2 on (__at1.f1 = __at2.f1 and __at1.f2 = __at2.f2)
where __at2.f1 is null and __at2.f2 is null

Има дублиращи се по f1, по f2, както и по двете.
Резултатът, както може да се очаква, е:

id f1 f2
----------- ----------- -----------
3 1 3
6 2 3
7 3 1
8 3 2
9 3 3

(5 row(s) affected)

Сега, ако изпълня същата заявка, но със сменено условие:

select __at1.id, __at1.f1, __at1.f2
from __at1
left join __at2 on (__at1.f1 = __at2.f1 and __at1.f2 = __at2.f2)
where __at2.f1 is null and __at2.f2 is not null

Резултатът, както може да се очаква, е:

id f1 f2
----------- ----------- -----------

(0 row(s) affected)

Не съм много сигурен как може да се получи резултат във втория случай.

Но както и да е, щом проблема е вече решен...

Редактирано от Formal на

Отговор
в отговор на kalinkina #11

Re: InsertSQL

Примерна таблА
1 13.12.2007 00:00:00 2 20000.00 1111111111111111111111 4
2 13.12.2007 00:00:00 2 25000.00 8888888888888888888888 12
3 13.12.2007 00:00:00 2 20000.00 1111111111111111111111 20

Примерна таблБ
1 14.2.2008 00:00:00 3 20000.00 1111111111111111111111 4
2 14.2.2008 00:00:00 3 25000.00 8888888888888888888888 12
3 14.2.2008 00:00:00 3 20000.00 1111111111111111111111 20
4 14.2.2008 00:00:00 3 4000.00 4444444444444444444444 28
5 14.2.2008 00:00:00 3 20000.00 1111111111111111111111 36



Резултата от Б-А трябва да върне записи 3,4,5 от Б
НО с условие "дай всички записи, които в таблА сума=НУЛЛ" намира само запис 4 /3 и 5 ги игнорира, защото ги счита за НОТ НУЛЛ/

.....
та ако query-to 'сума=НУЛЛ' се държеше нормално, нямаше да правя цялата гимнастика


мерси за съветите на всички и кат закъсам пак ще се оабдя

---
(на)здраве и късмет
Отговор
в отговор на kalinkina #12

Re: InsertSQL

Сега разбрах. В този случай мога да ти предложа следната заявка:
Примерни данни:

create table __at1 (id int, f1 int)
create table __at2 (id int, f1 int)

insert into __at1 values (1, 1)
insert into __at1 values (2, 2)
insert into __at1 values (3, 1)
insert into __at1 values (4, 1)
insert into __at1 values (5, 3)
insert into __at1 values (6, 2)

insert into __at2 values (11, 1)
insert into __at2 values (12, 2)
insert into __at2 values (13, 1)

И заявката:

select *
from __at1 t1a
where (select count(*)
from __at1 t1b
where t1b.f1 = t1a.f1
and t1b.id <= t1a.id)
> (select count(*)
from __at2 t2b
where t2b.f1 = t1a.f1)

С цел опростяване съм направил сравнението само по едно поле - за две полета трябва просто да се добави по още едно условие. Освен това в таблица 1 трябва да имаш уникално поле (аз съм го кръстил id). Ако нямаш такова, вероятно имаш проблем в дизайна на базата. При всички случаи, би трябвало да е лесно да се добави такова поле. Повечето от rdbms-ите имат нещо като 'autoincrement' или 'identity'.

Отговор