Autor Beitrag
Nico B.
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 45

Win XP
Delphi 2006 Prof.
BeitragVerfasst: Mi 25.11.09 13:31 
Hallo Leute,

ich habe 2 Datenbanken DB1 und DB2.
In DB1 gibt es die Tabelle T1 und in DB2 die Tabelle T2. Beide Tabellen sind ähnlich aufgebaut und enthalten eine Spalte Name als Index.

Folgendes SQL-Statement würde ich jetzt gern mit den ADO-Komponenten umsetzen. Ich weiß aber nicht wie.

SELECT T2.Name
FROM T1, T2
WHERE T2.Name NOT IN T1.Name

Mein Ziel ist es ein DBGrid mit den Namen aus T2 zu füllen, die aber nicht in T1 enthalten sind.
Wie muss ich das anstellen?
ene
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 779
Erhaltene Danke: 1

Vista, XP, W2K
Delphi, .Net, Deutsch und Englisch
BeitragVerfasst: Mi 25.11.09 14:21 
Hi,

Was für ein DBMS ist es denn und ist ggf, die T2 aus DB2 in DB1 verknüpft?

_________________
Wir, die guten Willens sind, geführt von Ahnungslosen, Versuchen für die Undankbaren das Unmögliche zu vollbringen.
Wir haben soviel mit so wenig so lange versucht, daß wir jetzt qualifiziert sind, fast alles mit Nichts zu bewerkstelligen.
Nico B. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 45

Win XP
Delphi 2006 Prof.
BeitragVerfasst: Mi 25.11.09 14:32 
Also es sind eigentlich 2 DBMS. Zum einen eine Access-DB und eine MSQSL-DB.
Daher kann ich das SQL-Statement nicht nutzen.

Meine Idee war daher. Mit einer ADOQuery alle Namen aus der MSSQL-Tabelle anzeigen zu lassen.
Anschließend hätte ich diese Ergebnisse irgendwie mit einer ADOQuery oder ähnlichem aus der Access-DB verknüpft.
Bspw.
SELECT Namen
FROM Access-Tabelle
WHERE Namen NOT IN (und hier jetzt das Ergebnis der ADOQuery aus der MSSQL-DB)

Aber wie?
Als Parameter gehts wohl nicht, weil man da keine ganzen Felder nehmen kann.
ene
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 779
Erhaltene Danke: 1

Vista, XP, W2K
Delphi, .Net, Deutsch und Englisch
BeitragVerfasst: Mi 25.11.09 14:42 
Man kann nicht in Access Tabellen aus MS SQL verknüpfen? Ist mir zwar neu, aber was solls...

Not In ist inperformant und sollte eigentlich durch ein LEFT JOIN und Prüfung auf Null ersetzt werden.

Du kannst dir ja auch alle Werte aus einer Tabelle in einem String zusammenschreiben und dann als Kriterium fürs Not In() verwenden :P

Ob Delphi so etwas unterstützt weiß ich nicht:

ausblenden SQL-Anweisung
1:
SELECT Namen FROM T1 LEFT JOIN T2 IN 'C:\DeineDB.mdb' ON T1.Feld = T2.Feld WHERE T2.ID Is Null					

_________________
Wir, die guten Willens sind, geführt von Ahnungslosen, Versuchen für die Undankbaren das Unmögliche zu vollbringen.
Wir haben soviel mit so wenig so lange versucht, daß wir jetzt qualifiziert sind, fast alles mit Nichts zu bewerkstelligen.
Nico B. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 45

Win XP
Delphi 2006 Prof.
BeitragVerfasst: Mi 25.11.09 14:54 
Es stört mich jetzt erst mal nicht das NOT IN inperformant ist (Aber danke für den Tipp).
Mit JOINS arbeite ich so gut wie nie. Daher ist es schwer für mich, mich da reinzudenken.
Vielleicht können wir es daher weiter mit NOT IN durchdenken.

Wenn NOT IN schon inperformant ist, was ist es dann meine Ergebnisse aus einer Tabelle in einen String zusammenzuschreiben? Zumal niemand weiß, wann der Ausdruck für einen String zu lang wird.

Ich habe gerade folgendes gefunden. Das klingt wie die Lösung die ich will, aber sie ist sehr kurz formuliert.
Vielleicht kannst du mir ja dabei helfen.

www.delphipraxis.net...dataset+verkn%FCpfen

Danke schon mal.
zuma
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 660
Erhaltene Danke: 21

Win XP, Win7, Win 8
D7 Enterprise, Delphi XE, Interbase (5 - XE)
BeitragVerfasst: Mi 25.11.09 15:09 
wenn dich die performance nicht stört, dann musste das eher so machen:

// zuerst alle 'Not in'-Wert merken
var lNamenDB2 : String;

while not T2.eof do
begin
lNamendb2 := lNamenDB2 + T2.FieldByName('NAME').AsString + ','
T2.next;
end;
lNamenDB2 := copy(lNamenDB2, 0, length(lNamenDB2)-1);

// und dann die 'Not in'-Werte verwenden
Format('SELECT Name FROM T2 WHERE Name NOT IN (%s), [lNamenDB2]);

_________________
Ich habe nichts gegen Fremde. Aber diese Fremden sind nicht von hier! (Methusalix)
Warum sich Sorgen ums Leben machen? Keiner überlebts!
ene
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 779
Erhaltene Danke: 1

Vista, XP, W2K
Delphi, .Net, Deutsch und Englisch
BeitragVerfasst: Mi 25.11.09 15:56 
Mich würde interessieren, warum du nicht in einem der beiden DBMS die Daten schon zusammenführst und dann einfach drauf zugreifst.

Da ich schon länger kein Delphi mehr benutze, habe ich auch keins zur Verfügung :(

_________________
Wir, die guten Willens sind, geführt von Ahnungslosen, Versuchen für die Undankbaren das Unmögliche zu vollbringen.
Wir haben soviel mit so wenig so lange versucht, daß wir jetzt qualifiziert sind, fast alles mit Nichts zu bewerkstelligen.
Nico B. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 45

Win XP
Delphi 2006 Prof.
BeitragVerfasst: Mi 25.11.09 16:13 
Zitat:
Wenn NOT IN schon inperformant ist, was ist es dann meine Ergebnisse aus einer Tabelle in einen String zusammenzuschreiben? Zumal niemand weiß, wann der Ausdruck für einen String zu lang wird.


Hallo zuma! Die Menge in einen String zu packen ist mir dann doch zu inperformant. Siehe Zitat.

@ene: Ich weiß nicht wie.

Momentan sieht es folgendermaßen aus.
Ich habe folgende Komponenten:
ADOConnectionAccess
ADODataSetAccess
ADODataSourceAccess
ADOConnectionMSSQL
ADODataSetMSSQL
ADODataSourceMSSQL
DBGrid

Die DataSet-Properties der DataSources stehen auf den jeweiligen ADODataSets.
Die Connection-Properties der DataSets stehen auf den jeweiligen ADOConnections.

Das ADODataSetAccess hat einen Parameter namens NameMSSQL.

Der CommandText des ADODataSetMSSQL lautet
ausblenden SQL-Anweisung
1:
SELECT NameMSSQL FROM TabelleMSSQL					


Der CommandText des ADODataSetAccess lautet
ausblenden SQL-Anweisung
1:
SELECT NameAccess FROM TabelleAccess WHERE NameAccess NOT IN (:NameMSSQL)					


Die DBGrid hat als DataSource die ADODataSourceAccess.

Lustigerweise erhalte ich jetzt genau das gegenteilige Ergebnis.
Ich sehe also alle Namen die in beiden Tabellen enthalten sind.
Ich will aber nur die Namen sehen, die in der TabelleAccess und nicht in der TabelleMSSQL stehen.

Was mach ich falsch? Ich bin doch so na dran.
ene
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 779
Erhaltene Danke: 1

Vista, XP, W2K
Delphi, .Net, Deutsch und Englisch
BeitragVerfasst: Do 26.11.09 08:52 
Access öffnen, Datei / Externe Daten / Tabellen verknüpfen / ODBC-Datenbanken und dann entweder eine neue DSN anlegen oder halt die vorhandene verwenden.

_________________
Wir, die guten Willens sind, geführt von Ahnungslosen, Versuchen für die Undankbaren das Unmögliche zu vollbringen.
Wir haben soviel mit so wenig so lange versucht, daß wir jetzt qualifiziert sind, fast alles mit Nichts zu bewerkstelligen.
Nico B. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 45

Win XP
Delphi 2006 Prof.
BeitragVerfasst: Do 26.11.09 11:07 
Hallo ene,

ich hatte mir schon gedacht, dass du etwas in der Richtung meinst.
Das kann ich aber leider nicht machen. Erstens habe ich kein Access. Die DB liegt auf einem anderen Rechner. Und zweitens kann/darf ich sie nur lesen.
ene
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 779
Erhaltene Danke: 1

Vista, XP, W2K
Delphi, .Net, Deutsch und Englisch
BeitragVerfasst: Do 26.11.09 12:14 
Darfst du denn auf den Server?

_________________
Wir, die guten Willens sind, geführt von Ahnungslosen, Versuchen für die Undankbaren das Unmögliche zu vollbringen.
Wir haben soviel mit so wenig so lange versucht, daß wir jetzt qualifiziert sind, fast alles mit Nichts zu bewerkstelligen.
Nico B. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 45

Win XP
Delphi 2006 Prof.
BeitragVerfasst: Do 26.11.09 14:03 
Hallo Leute,

ich habe die direkte Verknüpfung über Datenbankenkomponenten nun aufgegeben.
Letztendlich habe ich das Problem folgendermaßen gelöst:

In einer Query habe ich alle Datensätze der Access-DB aufgerufen und in einer anderen alle Datensätze der MSSQL-DB.
Anschließend bin ich per while-Schleife alle Datensätze der Access-Query durchgegangen und habe geprüft

ausblenden Delphi-Quelltext
1:
2:
3:
if not <Access-Querry>.Locate('Name',<MSSQL-Querry>.FieldByName('Name').AsString,[loCaseInSensitive,loPartialKey])
  then
    <Datensatz in eine StringGrid übertragen>


Glücklicherweise war es nicht ganz so langsam wie ich erwartet hatte.

Euch allen aber vielen Dank für eure Mühe.

@Borland: Ich schlage hiermit vor, eine Möglichkeit zu entwickeln, die mein Problem geschickter über Komponenten oder ähnliches löst.