0

"select's" in Funktion als Paremeter übergeben

Hallo,

Um einigermassen wartbare und wiederverwendbare Funktionen zu erstellen, möchte ich diese in Unterfunktionen auslagern. Nun gibt es immer wieder der Fall, dass die ausgelagerte Unterfunktion in einem Loop aufgerufen wird. 

Da die ausgelagerte Funktion, jedoch Zugriff auf Ninox Tabellen Records benötigt, müsste ich select's in der Unterfunktion machen, welche dann im Loop jeweils immer aufgerufen werden, was ja bekanntlich der Performance schadet. 

Nun Frage ich mich, wie ich trotzdem Funktionen auslagern kann, und das select vor dem Loop machen kann und als Parameter an die Funktion übergeben kann?

Gemäss meinen Tests geht das nicht: 
 

Oder gibt es da  eine Möglichkeit / Workaround, welchen ich noch nicht kenne? 

Weil wenn man nur auf die Performance schaut, müsste alles in einer Funktion abgehandelt werden, zuerst alle benötigten Daten per select in Variablen schreiben und im Loop filtern. Das gibt einfach elend lange, unübersichtliche, Funktionen.... 
 

7 Antworten

null
    • Pushing the Boundaries of Ninox
    • Gotje_Ing
    • vor 7 Stunden
    • Gemeldet - anzeigen

    Moin, 
    du musst hier ein Array of numbers übergeben, welches entweder als string oder besser als any übergeben wird. Mit split() bzw. parseJSON() kannst du das zurück in ein array verwandeln. Innerhalb der Function dann mit record() wieder greifen.

    Ein Array eines Typs (text, number, nodes/rid/nid, etc.) kann nie direkt an eine Funktion übergeben werden. 

      • m2apla gmbh
      • Fabian_Zusli
      • vor 3 Stunden
      • Gemeldet - anzeigen

       
      Danke für die Rückmeldung. Ich muss jedoch in der Unterfunktion dann per Filter auf die gesamte "select" zugreifen können. Also mit first(selection[name  = onlineName]) 
      Mit record() müsste ich ja exakt wissen, welchen Eintrag ich benötige, oder übersehe ich da etwas?

      Oder ist die Übergabe als Array of numbers und dann zurück per loop die Datensätze per record() wieder holen performance mässig effizienter als ein select in der Unterfunktion? 🙄

      • Pushing the Boundaries of Ninox
      • Gotje_Ing
      • vor 2 Stunden
      • Gemeldet - anzeigen

       
      Ein Select in der Funktion wäre performancetechnisch vorzuziehen, ist aber nicht immer möglich. 
      Wenn es nicht möglich ist:

      function MyFunction(ArrayInJson : any) do
        let arrayParsed := parseJSON(ArrayInJson.ArrayKey);
        let mySelection := for i in arrayParsed do
          record(Tabelle,number(i)).Nr
        end;
      end;
      let mySelect := select Table;
      MyFunction({ArrayKey: mySelect.number(Nr)})
      

      Dann hast du den gleichen Datentyp wie ein Select und kannst weiter filtern. 
       

      • m2apla gmbh
      • Fabian_Zusli
      • vor 2 Stunden
      • Gemeldet - anzeigen

       
      Ok, dann bleibt mir wohl nichts anderes, als die selects in der Unterfunktion in jedem Loop zu machen... 

      Wann ist dann ein select nicht möglich? 

      • Pushing the Boundaries of Ninox
      • Gotje_Ing
      • vor 2 Stunden
      • Gemeldet - anzeigen

       
      Wenn du eine Funktion extrem dynamisch aufbauen möchtest, also die Übergabe der verschiedenen benötigten Filter noch komplexer wird als die Übergabe von einem Array oder der select aufgrund der Datenmengen viel zu lange dauern würde. Dann kann man außerhalb vom Funktionsaufruf einmalig die passenden Records selecten und nur dieses kleine gefilterte Array übergeben.

      Aus einem Anwendungsfall, bei dem ich ca. 500.000 Records aus einer Tabelle in 10 Subsets handhaben musste, blieb mir nichts anderes übrig. Da kannst du den select innerhalb eines Loops praktisch vergessen und musst sauber vorher einmal alles gefiltert greifen und dann in die Funktion übergeben. 

      Noch ein Fall wäre, wenn du für die Filter diverse Sub-Records brauchst, die auch alle eine gewisse Größe haben. Dann lädt sich der Loop pro Schleife einmal auch alle Sub-Records. Das ergibt exponentiell mehr Rechenaufwand. Lieber einmal außerhalb sauber filtern/splitten, dann geht es einfacher.

      Grüße Philipp

      • m2apla gmbh
      • Fabian_Zusli
      • vor 1 Stunde
      • Gemeldet - anzeigen

       

      Danke Philipp für deine Erläuterungen...
      Eine solche Vorfilterung könnte in gewissen Fällen tatsächlich noch einen Vorteil bringen. 

      Wie ist deine Erfahrung, einer "Data Page" bezüglich Performance. 
      Also wenn bspw. deine 500'000 records, mit der dataPage 1:N verknüpft sind und dann nicht per select der Zugriff geschieht sondern per record(dataPage,1).myLargeTable?

      • Pushing the Boundaries of Ninox
      • Gotje_Ing
      • vor 1 Stunde
      • Gemeldet - anzeigen

       
      Dies ist nicht zu empfehlen.
      Die Rückverknüpfung ist im Hintergrund nichts anderes als ein Textfeld, in dem dann 500k Record-IDs stehen. 
      Das ist ein sehr sehr langer Text, der bekanntermaßen Probleme macht, ganz zu schweigen vom Änderungslog. 
      record() ist eine der schnellsten Zugriffsvarianten und ist nach meinen Tests in der Regel gleich schnell wie eine Verknüpfung, in gewissen Konstellationen sogar schneller.
      Daher ist für kleine Recordzahlen eine Verknüpfung oder eine dyn. Mehrfachauswahl sinnvoll, bei großen Recordzahlen ein select where mit korrekter Filter-Reihenfolge. 

Content aside

  • vor 1 StundeZuletzt aktiv
  • 7Antworten
  • 23Ansichten
  • 2 Folge bereits