Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Zeileninhalt direkt aus Parameter erzeugen (https://www.delphipraxis.net/199802-zeileninhalt-direkt-aus-parameter-erzeugen.html)

FediDelPr 20. Feb 2019 22:17

Datenbank: ACCESS • Version: 2016 • Zugriff über: ADO

Zeileninhalt direkt aus Parameter erzeugen
 
Hallo SQL Cracks,

ich möchte folgenden Ausdruck vereinfachen:

Delphi-Quellcode:
SELECT DISTINCT Parent FROM Hierarchie h1a WHERE (h1a.Parent = :ParamInteger1)


Ziel ist eine Tabelle die lediglich je eine Zeile/Spalte also ein Feld enthält,
wobei der Inhalt gleich dem Parameter ist.

Der Ausdruck wird nachher mit UNION mit weiteren Zeilen ergänzt.

Sicher ganz einfach.

hoika 21. Feb 2019 00:01

AW: Zeileninhalt direkt aus Parameter erzeugen
 
Halo,
so wie Du beschreibst, sollte die Abfrage doch genau das liefern?

Wo ist denn das Problem?

FediDelPr 21. Feb 2019 00:56

AW: Zeileninhalt direkt aus Parameter erzeugen
 
Das Problem ist vielleicht mehr akademischer Art.

Ich suche gerne nach möglichst einfachen, leicht verständlichen Lösungen.

Dieser Ausdruck kommt wegen etwa 10 UNION immer wieder vor.

Jasocul 21. Feb 2019 07:27

AW: Zeileninhalt direkt aus Parameter erzeugen
 
Meinst du sowas:
Code:
select :ParamInteger1
Bei MS-SQL kann man das machen. Wie es in Access ist, musst du ausprobieren.

mkinzler 21. Feb 2019 07:47

AW: Zeileninhalt direkt aus Parameter erzeugen
 
Oder
SQL-Code:
SELECT :ParamInteger1 as Parent FROM Hierarchie;

FediDelPr 21. Feb 2019 10:15

AW: Zeileninhalt direkt aus Parameter erzeugen
 
Variante Jasocul, die kürzeste, funktioniert tatsächlich.

Ich war vermutlich bis anhin über den Eintrag von Parametern im ADOQueryx gestolpert.
Wie und wann diese Einträge genau funktionieren ist mir noch nicht klar.
Mein Eindruck: manchmal bleiben alte Relikte hängen.
Werde ich noch anschauen müssen oder jemand hilft mir auf die Sprünge.


Variante mkinzler

Diese wird grundsätzlich akzeptiert, liefert aber für für jede Zeile der Tabelle dasselbe Resultat.
Leider lässt sich aus irgendeinem Grund DISTINCT nicht anwenden.

FediDelPr 21. Feb 2019 14:51

AW: Zeileninhalt direkt aus Parameter erzeugen
 
Ja so einfach scheint's nun doch wieder nicht zu sein:

Beim Einbinden in weiteren SELECT wird doch eine Tabelle oder Abfrage verlangt.

Dann wird's komplizierter / instabiler:
Auch der einfache Ausdruck (SELECT : ParamIntereger1) funktioniert nun nicht mehr, es
erscheint die Fehlermeldung:
Delphi-Quellcode:
    Fehler bei einem aus mehreren Schritten bestehenden OLE DB-Vorgang.
    Prüfen Sie die einzelnen OLE DB-Statuswerte, falls vorhanden.
    Die Daten wurden nicht verarbeitet.
Auch nach Neustart von Delphi und Schliessen/Oeffnen der DB kommt immer noch diese
Fehlermeldung (im Debugmodus).
Aber: Wenn ich das Programm einfach durchlaufen lasse (anstatt Activate = TRUE im Debug-Modus) kommt keine Fehlermeldung und das Resultat wird richtig erzeugt. Eigenartig.

Delphi.Narium 21. Feb 2019 15:42

AW: Zeileninhalt direkt aus Parameter erzeugen
 
Ehrlichgesagt hab' ich nicht kapiert, was Du da so bauen möchtest.

Fangen wir mal beim alten, guten Oracle an. Dort gibt es eine Tabelle Dual, die man für so allerlei "missbrauchen" kann.
SQL-Code:
create table dual (dummy Varchar(1));
insert into dual (dummy) values ('X');
Wenn man nun einen Wert braucht, den es in keiner Tabelle gibt, geht das z. B. mit
SQL-Code:
select sysdate from dual
Sinngemäß entspricht das einem
SQL-Code:
select :ParamInteger1
, wobei diese Select-Syntax ohne from nicht von allen Datenbanken verstanden wird. Es gibt da unterschiedliche Hilfskonstrukte.

Soweit so gut so theoretisch:

Vermutlich möchtest Du sowas:
SQL-Code:
select :Parameter1 from dual
union
select :Parameter2 from dual
union
select :Parameter3 from dual
union
select :Parameter4 from dual
union
select :Parameter5 from dual
union
select :Parameter6 from dual
union
select :Parameter7 from dual
union
select :Parameter8 from dual
union
select :Parameter9 from dual
union
select :Parameter10 from dual
Die per Select geholten Werte existieren nicht in der Datenbank, sondern sollen per Parameter in eine Ergebnismenge "reingewuselt" werden.

Das Ergebnis diese Konstruktes könnte man dann beliebig (per Join, als In-Klausel, where Exists ...) in beliebige Abfragen einbauen.

Suchst Du was in diese Richtung?

Aber: Parameter werden für gewöhnlich nur in der Where-Klausel akzeptiert und nicht als "Selectergebnis" oder für Tabellen-, Spaltennamen, ...

Das oben Skizzierte wird also mit an Sicherheit grenzender Wahrscheinlichkeit scheitern.

jobo 21. Feb 2019 21:36

AW: Zeileninhalt direkt aus Parameter erzeugen
 
Zitat:

Zitat von FediDelPr (Beitrag 1426175)
Variante mkinzler

Diese wird grundsätzlich akzeptiert, liefert aber für für jede Zeile der Tabelle dasselbe Resultat.
Leider lässt sich aus irgendeinem Grund DISTINCT nicht anwenden.

So wie es da steht, ist es auch genau so gedacht. Wenn die Tabelle 10000 Datensätze hat, kommt für jeden der Datensätze der Wert des (gleichen) Parameters zurück.

Du könntest vielleicht wirklich mal verraten, was Du erreichen möchtest. Also nicht: ich brauch 10 Union, sondern wofür Du das einsetzt, welche Werte da drinstehen sollen, warum genau diese Werte, also ganz einfach den Anwendungsfall. Vielleicht gibt es eine Abkürzung für Dein Vorhaben.
- Z.B. eine virtuelle Datenquelle mit definierten Werten?
- ..?
Wenn ja, würde man vielleicht am ehesten eine (temporäre )Tabelle erzeugen und dort per Insert die benötigten Werte eintragen und damit weiterarbeiten.
Falls das in bestehende Objekte eingebunden werden muss, kann man Dimensionen wie User, Session in der Tabelle definieren und diese on the fly mitverwalten.

p80286 21. Feb 2019 22:43

AW: Zeileninhalt direkt aus Parameter erzeugen
 
Delphi-Quellcode:
    Fehler bei einem aus mehreren Schritten bestehenden OLE DB-Vorgang.
    Prüfen Sie die einzelnen OLE DB-Statuswerte, falls vorhanden.
    Die Daten wurden nicht verarbeitet.
Das ist die unnachahmlich effizente Methode von ADO, Dir mitzuteilen, daß Du die Syntax Deiner Abfrage einmal überprüfen solltest.

Gruß
K-H
P.S.
das "SELECT DISTINCT Parent FROM Hierarchie h1a WHERE (h1a.Parent = :ParamInteger1)" bedeutet "Es gibt mindestens einen Datensatz mit Parent=Parameterinteger"

FediDelPr 22. Feb 2019 01:58

AW: Zeileninhalt direkt aus Parameter erzeugen
 
Zur Problemstellung:

Es geht um die Erzeugung einer bestimmten Abbildung aus einer Baumstruktur bzw. einer (geordneten)
Hierarchie. Für jeden Hierarchie-Level werden Einträge erzeugt. Für den ersten Level
nur einen.
Die zu Grunde liegenden Daten sind in einer einfachen Linktabelle organisiert. (ArtLink und
Parent)
Einziger Eingangsparameter ist ein Link (Referenz) auf das Top-Element.

Delphi-Quellcode:
GerätXY                                 <= Top-Element
   Gehäuse
      Gehäuse-Boden
      Gehäuse-Deckel
   Netzteil
      Netzteil-Gehäuse
      ElektronikBoard zu Netzteil

 .... etc.
Zum besseren Verständis sind hier konkrete Assemblies/Komponenten eingetragen.
Die Hierarchie-Tabelle enthält in Wirklichkeit nur die Verlinkungen (und Sortierinfos)

Ich gebe mal den Code wieder der fast richtig arbeitet. Er würde eben wie gewünscht laufen, wenn
der erste Select nach dem UNION nur ein Element (nämlich den Parameter selbst) liefern würde.
Zurzeit entstehen zusätzliche Zeilen.

Der Code ist hier für 3 Hierarchie-Level wiedergegeben und wird schlussendlich auf 10 Level ausgebaut.
Eine rekursive Implementation wäre sicher wünschenswert, aber allenfalls Gegenstand einer späteren
Betrachtung.

Delphi-Quellcode:
   SELECT
     Parent,
     HLevel,
     Bezeichnung,
     Srt
   FROM
     (
   SELECT DISTINCT Parent, 1 AS HLevel, '000000' AS Srt FROM Hierarchie h1a WHERE (h1a.Parent = :ParamInteger1)

   UNION

   SELECT
     h1.ArtLink AS Level1,
     2 AS HLevelx,
     '00' & h1.Sort & '00' AS Srt
   FROM
     (
1       (SELECT ArtLink, Parent, Sort FROM Hierarchie h1a WHERE (h1a.Parent = :ParamInteger2)) h1
      LEFT JOIN Hierarchie h2 ON (h1.ArtLink = h2.Parent))

   UNION

   SELECT
     h2.ArtLink AS Level2,
     3 AS HLevel,
     '00' & h1.Sort & h2.Sort AS Srt
   FROM
     ((
2       (SELECT ArtLink, Parent, Sort FROM Hierarchie h1a WHERE (h1a.Parent = :ParamInteger3)) h1
      LEFT JOIN Hierarchie h2 ON (h1.ArtLink = h2.Parent))
      LEFT JOIN Hierarchie h3 ON (h2.ArtLink = h3.Parent))
     ) ha

   LEFT JOIN Artikel ar ON (ha.Parent = ar.ArtikelID)

   ORDER BY Srt
Die bezeichneten Zeilen (1,2) sind noch ungenügend, es darf nur ein Element erzeugt werden.
Bei ParamInteger1,2,3 wird der gleiche Wert übergeben.

Ich habe schon Lösungen, diese benötigt aber auf jedem Hierarchie-Level einen
zusätzlichen SELECT bzw. Massnahmen für die Elimination von Zeilen mit NULL-Werten.
Bei der Lösung geht es nicht um Laufzeit-Betrachtungen.
Bis anhin(ähnliche Auswertungen) ist alles äusserst schnell.
Es geht mir mehr um kompakten und sauberen Code, leicht verständlich, gut wartbar, nichts Unnötiges/Redundantes.

Und.. ich weiss es gibt bessere DBs als ACCESS, aber das steht aus bestimmten Gründen zurzeit
nicht zur Diskussion.

Jasocul 22. Feb 2019 08:05

AW: Zeileninhalt direkt aus Parameter erzeugen
 
Zitat:

Zitat von FediDelPr (Beitrag 1426223)
Die bezeichneten Zeilen (1,2) sind noch ungenügend, es darf nur ein Element erzeugt werden.

Laut deiner Darstellung der Geräteliste muss es unter (1) zwei Ergebniszeilen geben (Gehäuse und Netzteil).
Dementsprechend unter (2) vier Zeilen (Gehäuse-Boden, Gehäuse-Deckel, Netzteil-Gehäuse und ElektronikBoard zu Netzteil).

Sollte meine Analyse falsch sein, verstehe ich da wohl etwas nicht.


Zitat:

Zitat von FediDelPr (Beitrag 1426223)
Bei ParamInteger1,2,3 wird der gleiche Wert übergeben.

Dann nimm auch nur einen Parameter. Es sei denn, du musst für zukünftige Aufgaben an der Stelle mit unterschiedlichen Paramtern rechnen.

Ich habe mal versucht, dein Aufgabe unter den gesetzten Bedingungen auf meine Weise zu lösen. Da ich kein Access zur Verfügung habe, ist das natürlich ins blaue getippt und völlig ungeprüft!
Unter MS-SQL, Oracle o.ä. würde ich das vermutlich eher mit einer User-Defined-Function lösen. Wobei das aber sehr von der exakten Aufgabe abhängt. Für eine Visualisierung in einer Anwendung, würde ich sicher andere Wege gehen.

Hier mein Ansatz:
Code:
SELECT *
  FROM (
 
SELECT 1 AS HLevel,
       AR.Bezeichnung,
       '000000' AS Srt
  FROM Hierarchie H1
  LEFT JOIN Artikel AR
       ON AR.ArtikelID = H1.Parent
 WHERE H1.Parent = :ParamInteger1

UNION

SELECT 2 AS HLevel,
       AR.Bezeichnung,
       '00' & h2.Sort & '00' AS Srt
  FROM Hierarchie H1
  LEFT JOIN Hierarchie H2
       ON H2.ArtLink = H1.Parent
  LEFT JOIN Artikel AR
       ON AR.ArtikelID = H2.ArtLink
 WHERE H1.Parent = :ParamInteger2

UNION

SELECT 3 AS HLevel,
       AR.Bezeichnung,
       '00' & h2.Sort & h3.Sort AS Srt
  FROM Hierarchie H1
  LEFT JOIN Hierarchie H2
       ON H2.ArtLink = H1.Parent
  LEFT JOIN Hierarchie H3
       ON H3.ArtLink = H2.ArtLink
  LEFT JOIN Artikel AR
       ON AR.ArtikelID = H3.ArtLink
 WHERE H1.Parent = :ParamInteger3

 )

 order by Srt

p80286 22. Feb 2019 08:25

AW: Zeileninhalt direkt aus Parameter erzeugen
 
Zitat:

Zitat von Jasocul (Beitrag 1426228)
Dann nimm auch nur einen Parameter.

Das könnte in die Hose gehen. Wenn ich mich richtig erinnere darf bei ADO ein Parameter nur einmal genutzt werden.

Gruß
K-H

Jasocul 22. Feb 2019 08:37

AW: Zeileninhalt direkt aus Parameter erzeugen
 
Zitat:

Zitat von p80286 (Beitrag 1426229)
Zitat:

Zitat von Jasocul (Beitrag 1426228)
Dann nimm auch nur einen Parameter.

Das könnte in die Hose gehen. Wenn ich mich richtig erinnere darf bei ADO ein Parameter nur einmal genutzt werden.

OK, das war mir nicht bekannt. Fehlende ADO-Erfahrung :wink:

FediDelPr 22. Feb 2019 09:39

AW: Zeileninhalt direkt aus Parameter erzeugen
 
Vielen Dank für's mitdecken.
Bin voraussichtlich mindestens bis Sonntag abwesend (ohne PC-Zugang).
Bis dann.

Schokohase 22. Feb 2019 10:15

AW: Zeileninhalt direkt aus Parameter erzeugen
 
Zitat:

Zitat von p80286 (Beitrag 1426229)
Zitat:

Zitat von Jasocul (Beitrag 1426228)
Dann nimm auch nur einen Parameter.

Das könnte in die Hose gehen. Wenn ich mich richtig erinnere darf bei ADO ein Parameter nur einmal genutzt werden.

Das Thema haben wir schon beantwortet und deine Erinnerung ist trübe.
https://www.delphipraxis.net/199766-...ml#post1425912

Jasocul 22. Feb 2019 13:05

AW: Zeileninhalt direkt aus Parameter erzeugen
 
Zitat:

Zitat von Schokohase (Beitrag 1426238)
Das Thema haben wir schon beantwortet und deine Erinnerung ist trübe.

Das würde bedeuten, dass ich das Thema gelesen haben müsste. :wink:

Aber wenn wir schon dabei sind, geht vielleicht sowas mit ADO / ACCESS:
Code:
Declare @Param1 int = :ParamInteger1

...
SELECT 1 AS HLevel,
       AR.Bezeichnung,
       '000000' AS Srt
  FROM Hierarchie H1
  LEFT JOIN Artikel AR
       ON AR.ArtikelID = H1.Parent
 WHERE H1.Parent = @Param1

UNION

SELECT 2 AS HLevel,
       AR.Bezeichnung,
       '00' & h2.Sort & '00' AS Srt
  FROM Hierarchie H1
  LEFT JOIN Hierarchie H2
       ON H2.ArtLink = H1.Parent
  LEFT JOIN Artikel AR
       ON AR.ArtikelID = H2.ArtLink
 WHERE H1.Parent = @Param1
...


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:46 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz