AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Array mit DB Ergebnismenge vergleichen
Thema durchsuchen
Ansicht
Themen-Optionen

Array mit DB Ergebnismenge vergleichen

Ein Thema von rokli · begonnen am 15. Mai 2018 · letzter Beitrag vom 16. Mai 2018
Antwort Antwort
Jumpy

Registriert seit: 9. Dez 2010
Ort: Mönchengladbach
1.740 Beiträge
 
Delphi 6 Enterprise
 
#1

AW: Array mit DB Ergebnismenge vergleichen

  Alt 15. Mai 2018, 13:28
In Oracle könnte man das mit Hilfe der Dummy-Tabelle DUAL so lösen:

SQL-Code:
Select * From (
SELECT 'PAULas Name, (Select count(*) From Tabelle Where Name='PAUL') as ANZAHL FROM DUAL
UNION ALL SELECT 'KLAUSas Name, (Select count(*) From Tabelle Where Name='KLAUS') as ANZAHL FROM DUAL
UNION ALL SELECT 'PETERas Name, (Select count(*) From Tabelle Where Name='PETER') as ANZAHL FROM DUAL
-- usw.
) Where ANZAHL=0
Ralph
  Mit Zitat antworten Zitat
rokli

Registriert seit: 21. Mär 2009
Ort: Rödinghausen
303 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Array mit DB Ergebnismenge vergleichen

  Alt 15. Mai 2018, 13:45
Hallo Jumpy,

danke, verwende allerdings MS SQL! Hatte mal was mit "HAVING" probiert, geht aber nicht, weil aus der Abfrage ja kein <NULL> Satz hervorgeht, sondern <gar kein> Satz.

Hallo Mischerr,

das hat was! Ich kann gar nicht nach denen suchen kann, die NICHT da sind, sondern nur die ausschließen, die vorhanden sind! Very cool - Danke.
Rolf
wenn nicht anders angegeben, schreibe ich zu D7, XE2 und MS SQL - ansonsten fragen Sie ihren Administrator oder einen Operator. Update 06/2020: Delphi 10.4 Sydney
  Mit Zitat antworten Zitat
Jumpy

Registriert seit: 9. Dez 2010
Ort: Mönchengladbach
1.740 Beiträge
 
Delphi 6 Enterprise
 
#3

AW: Array mit DB Ergebnismenge vergleichen

  Alt 15. Mai 2018, 14:03
Die MSSQL-Version wäre dann:

SQL-Code:
SELECT 'PAULas Name Where (Select count(*) From Tabelle Where Name='PAUL') = 0
UNION SELECT SELECT 'KLAUSas Name Where (Select count(*) From Tabelle Where Name='KLAUS') = 0
UNION SELECT SELECT 'PETERas Name Where (Select count(*) From Tabelle Where Name='PETER') = 0
Da sollten dann nur die Einträge ohne Namen rauskommen
Ralph

Geändert von Jumpy (15. Mai 2018 um 14:08 Uhr)
  Mit Zitat antworten Zitat
rokli

Registriert seit: 21. Mär 2009
Ort: Rödinghausen
303 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Array mit DB Ergebnismenge vergleichen

  Alt 15. Mai 2018, 15:34
Hi Jumpy,

ich hatte das mit der "DUAL" Tabelle nicht verstanden. Aber Du hast Recht!

In der IBM DB2 (die habe ich gerade im Zugriff) Lösung sieht das dann so aus:

Code:
SELECT 'PAUL' AS Name FROM sysibm.sysdummy1 WHERE (SELECT COUNT(*) FROM Tabelle WHERE VARI = 'PAUL') = 0
UNION
SELECT 'KLAUS' AS Name FROM sysibm.sysdummy1 WHERE (SELECT COUNT(*) FROM Tabelle WHERE VARI = 'KLAUS') = 0
UNION
SELECT 'PETER' AS Name FROM sysibm.sysdummy1 WHERE (SELECT COUNT(*) FROM Tabelle WHERE VARI = 'PETER') = 0
und bringt die Namen raus, die eigentlich gar nicht vorhanden sind!

Dank und Gruß
Rolf
wenn nicht anders angegeben, schreibe ich zu D7, XE2 und MS SQL - ansonsten fragen Sie ihren Administrator oder einen Operator. Update 06/2020: Delphi 10.4 Sydney
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.749 Beiträge
 
Delphi 12 Athens
 
#5

AW: Array mit DB Ergebnismenge vergleichen

  Alt 15. Mai 2018, 16:10
Viele DBMS können mit Array-Parametern umgehen und es gibt DB-Zugriffskomponenten, welche das ebenfalls durchreichen können.
SQL-Code:
SELECT Name, COUNT(*) AS Anz
FROM Tabelle
WHERE Name IN :ArrayParameter
GROUP BY Name
ORDER BY Anz ASC

-- SQL.ParamByName('ArrayParameter').ArrayIrgendwas[0] := 'PAUL'; ...
-- SQL.ParamByName('ArrayParameter').ArrayIrgendwas := ['PAUL', 'KLAUS', ...];
-- SQL.ParamByName('ArrayParameter').SetArrayIrgendwas(['PAUL', 'KLAUS', ...]);
-- oder SonstWie
Leider geht das nicht überall, aber da gibt es auch einen Trick.
* den ganze SQL-String manuell zusammensetzen
* oder Makros und nur diesen einen Teil selber basteln
SQL-Code:
SELECT Name, COUNT(*) AS Anz
FROM Tabelle
WHERE Name IN (&ArrayMacro)
GROUP BY Name
ORDER BY Anz ASC

-- SQL.MacroByName('ArrayMacro').Value := 'a,b,c'; // siehe (1)
1) Ich hab das bisher vorallem mit Integern gemacht, da ist es extrem einfach über eine ArrayToString-Funktion aus dem Array [1,2,3] einen '1,2,3' String zu generieren, ohne auf das Quoting achten zu müssen.
Für Strings sollte man hier "unbedingt" die Quote-Funktion der DB-Zugriffskomponenten verwenden und damit den String erzeugen.
also sowas wie http://php.net/manual/de/function.my...ape-string.php
bzw. quote_name, quote_value, quote_literal oder z.b. TPgTextConverter.EscapeString (PgDAC).
'''PAUL'', ''KLAUS'', ...'
Delphi-Quellcode:
S := '';
for i := 0 to High(DeinArray) do begin
  if S <> 'then S := S + ', ';
  S := S + DBQuoteValueFunction(DeinArray[i]);
end;

PS: https://modern-sql.com/de/anwendung/select-ohne-from
SQL-Code:
--SELECT n
--FROM (VALUES ('Peter'), ('Klaus'), ('Paul'), ('Theo'), ('Bernd')) AS t(n)
--LEFT JOIN tabelle ON name = n
--WHERE ... weiß ich grade nix ... halt irgendwas mit count()=0 oder so

SELECT n
FROM (VALUES ('Peter'), ('Klaus'), ('Paul'), ('Theo'), ('Bernd')) AS t(n)
WHERE not exists(SELECT * FROM tabelle WHERE upper(name) = upper(n))
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (15. Mai 2018 um 16:30 Uhr)
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.602 Beiträge
 
Delphi 7 Professional
 
#6

AW: Array mit DB Ergebnismenge vergleichen

  Alt 15. Mai 2018, 16:27
Also die Idee mit der Tabelle Dual von Oracle finde ich gut.

Da ich aber überwiegend mit FireBird arbeite, lege ich mir dort in jeder Datenbank die Tabelle Dual an und schon kann ich alles so lösen, wie ich es von Oracle gewohnt bin. (Und brauche mir bei der Portierung von DB-System A nach DB-System B keinen Kopp machen, ob die SQLs unverändert übernommen werden können oder nicht )

Was spricht dagegen, diese Lösung auch bei anderen Datenbanken einzusetzen?
SQL-Code:
create table dual(dummy char(1));
insert into dual (dummy) values ('X');
commit;
(Mehr ist Dual unter Oracle auch nicht )
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.749 Beiträge
 
Delphi 12 Athens
 
#7

AW: Array mit DB Ergebnismenge vergleichen

  Alt 15. Mai 2018, 16:32
@Delphi.Narium: Warum keine Temp-Table? (am Besten nur für diese Session)

Ich war davon ausgegangen, dass es mehrere Nutzer mit dem Namen "Bernd" geben könnte, also auch mehrere Datensätze,
aber im Printip geht es dann auch wie bei Uwe Raabe, aber vielleicht noch mit einem DISTINCT usw.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (15. Mai 2018 um 16:34 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.824 Beiträge
 
Delphi 12 Athens
 
#8

AW: Array mit DB Ergebnismenge vergleichen

  Alt 15. Mai 2018, 16:40
Ich war davon ausgegangen, dass es mehrere Nutzer mit dem Namen "Bernd" geben könnte, also auch mehrere Datensätze,
aber im Printip geht es dann auch wie bei Uwe Raabe, aber vielleicht noch mit einem DISTINCT usw.
In der konstruierten A-Tabelle gibt es jeden Namen nur einmal. Da der JOIN ja bewusst ins Leere läuft, können wir uns das DISTINCT sparen.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.602 Beiträge
 
Delphi 7 Professional
 
#9

AW: Array mit DB Ergebnismenge vergleichen

  Alt 15. Mai 2018, 17:54
@Delphi.Narium: Warum keine Temp-Table? (am Besten nur für diese Session)
Um es auf allen Systemen gleich zu haben und nicht bei der Portierung immer daran zu denken:

Hier hab' ich die Tabelle, dort ist es eine Temp-Tabelle, die ich mir ggfls. anlegen bzw. befüllen muss. Anderswo geht ein Select auch ohne Angabe eines Tabellennamens, ...

'ne Temp-Tabelle für eine Session muss ich dann pro Session entsprechend "versorgen". Pech, wenn ich dann "mal eben" von FireBird nach Oracle wechsel, dann muss ich den entsprechenden Quelltext "weglassen", brauche also ein (wenn auch nur marginal) andere Implementierung. Mag es halt, wenn ein Programm unverändert gegen jede x-beliebige Datenbank läuft. Sorge halt dafür, dass auf Datenbankseite eine möglichst große Übereinstimmung besteht, sodass ich mir im Programm keine Gedanken darüber machen muss, welcher Quelltextbereich, welche SQLs ... nun bei der Nutzung von Datenbank X zu nehmen sind, welche bei Datenbank Y und was muss ich morgen machen, wenn noch Datenbank Z unterstützt werden soll?

Mit der Einheitlichkeit der SQL-Möglichkeiten zwischen den verschiedenen Datenbanken ist es ja nunmal nicht so weit her. (Wie man ja auch hier an den unterschiedlichen Lösungen sehen kann.)

Meine Lösung sieht halt so aus, dass ich für möglichst große Einheitlichkeit auf Datenbankseite sorge. Und da scheint mir das einmalige Anlegen und Befüllen der Tabelle Dual eben ein gangbarer Weg zu sein. (Und ja, es ist nur einer von vielen möglichen.)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.824 Beiträge
 
Delphi 12 Athens
 
#10

AW: Array mit DB Ergebnismenge vergleichen

  Alt 15. Mai 2018, 16:31
Bei MSSQL sollte auch folgendes Statement alle Namen auflisten, die nicht im obigen SELECT vorkommen
SQL-Code:
SELECT A.Name
FROM (VALUES ('Peter'), ('Klaus'), ('Paul'), ('Theo'), ('Bernd')) AS A(Name)
LEFT JOIN Tabelle B ON (A.Name= B.Name)
WHERE (B.Name IS NULL)
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:09 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz