Zum Inhalt springen

dr.dimitri

Mitglieder
  • Gesamte Inhalte

    1.276
  • Benutzer seit

  • Letzter Besuch

Alle Inhalte von dr.dimitri

  1. Zu ungeduldig er ist. Wieso nimmst nicht einfach v$sqlarea? Das Feld sql_fulltext ist ein CLOB und enthält das komplette SQL. Zu allem anderen: Man muss die Anwendung schon kennen die man tunen möchte bzw. sollte jemanden dabei haben der sie kennt (sofern es sich nicht einfach um einen vergessenden Index handelt). Ansonsten sollte man beim Tuning oben Anfangen: 1. Was muss die Anwendung fachlich erledigen? Wieviel zeit darf sie dafür benötigen, wieviel Zeit benötigt sie aktuell. 2. Gibt es Anforderungen, die vielleicht nicht mehr benötigt werden bzw. vereinfacht werden können und die man aus der Anwendung entfernen kann? Hierzu auch Punkt 3 miteinbeziehen. 3. Welche Teile in der Anwendung brauchen am Längsten? Top 10 Liste aufstellen und mit Punkt 2 vergleichen. 4. Ermitteln, ob die Top10 wirklaich aufgrund von SQL Statements in die Liste gekommen sind oder es sich um andere Komponenten handelt, die unnötig viel Zeit benötigen (Netzwerk, unperformanter Programmteil etc.) Logging innerhalb der Anwendung ist hier von Vorteil. 5. SQLs prüfen, ggf. tunen. 6. Datenbank Struktur anpassen, Instance Tuning 7. Hardware aufrüsten. Dazwischen immer wieder Ergebniskontrollen, ob die geforderten Zeiten schon erreicht wurden. Dim PS: Woran lag das RAC Problem?
  2. Windows selbst hat doch auch Tools von Haus aus dabei. Evtl. kann Dir da jemand aus dem Windowsforum helfen. Nicht der Rechner, sondern der DB Server. Den kann man ja mit 10MB starten oder 3GB - je nach Konfiguration. Kommt auf die Abfrage und die Datenbank an. Bei 2 Sekunden Laufzeit ist das aber nicht relevant. Wie sieht denn die CPU Auslastung aus? Dim
  3. Eigentlich passt keines dieser Programme dazu. Du kannst mit PHP aber sowohl serverseitige Programme schreiben also auch Programme, die Du einfach auf der Kommandozeile startest - ohne Apache dazwischen. Vielleicht ist das damit gemeint. phpMyAdmin ist ein Programm, welches mit PHP geschrieben wurde und serverseitig läuft. Dim
  4. PHP ist, wie schon erwähnt, eine Programmiersprache, mit der Du serverbasierte Anwendungen schreiben kannst. Das gilt aber auch für Java, C++, Perl, C# etc. etc. Darum handelt es sich aber noch nicht um einen Server. Dim
  5. Solange ihr keine messbaren Belege dafür liefert, glaube ich das als Informatiker und alter Tuning Spezi auch nicht. Eine seltsame Logik. Habt ihr das mal verifiziert? Muss der Server Speicher auslagern? Mit wie viel Speicher ist denn der SQL Server denn überhaupt konfiguriert? Gehen wir mal von 2,5GB aus, dann müssten die 3 Abfragen pro Sekunde ca. 1,5GB belegen, damit ihnen in 1,5 Sekunden der Speicher ausgeht. Liefert euer Plattensystem diese Datenmengen? Wisst ihr welche Datentransferrate ihr habt maximal habt und wie viel davon benutzt wird? Wenn eine Abfrage schnell und drei parallele Abfragen langsam sind, würde ich eher mal auf einen CPU Engpass tippen, denn bei den Zeiten dürfte man Full Tablescans auf riesige Tabelle ausschließen (sofern ihr nicht eine alte Notebookplatte in dem Server stecken habt, die schon bei einem kleinen Indexzugriff in die Knie geht). Alternativ könnte es natürlich auch sein, dass sich die Abfragen gegenseitig blockieren. MSSQL bietet ja, soweit ich weiß, auch das "Feature", dass ein lesender Prozess einen anderen lesenden blockiert. In diesem Fall würden weder Memory, noch CPU noch Plattenaufrüstung sondern nur Applicationstuning helfen. Dim
  6. Es wär auch nicht das erste mal, dass nach einer solchen "blinden" Hardwareaufrüstung die Performance noch schelchter wurde, da man auf den eigentlichen Flaschenhals jetzt noch mehr einprügeln kann. Dim
  7. Hmm wenn ich die Doku richtig verstanden hab, dann wäre aber ROWLOCK Dein Wunschkandidat. Dim
  8. Hmm erwischt. Da hab ich mal wieder Oracle auf auf andere Datenbanken übertragen ohne nachzuforschen ob es das dort gibt. Dim
  9. Die Lösung von streffin ist leider nicht ganz wasserdicht, denn wenn Du prüfst, ob deine neue Spalte schon gefüllt ist, kann diese schon aktualisiert aber noch nicht committet sein. Damit überschreibst Du kurze Zeit später den Wert den die andere Session reingeschrieben hat. Was passiert, wenn die Rechnerzeit nicht stimmt oder wenn sich ein User mehrfach angemeldet hat wollen wir hier gar nicht weiter vertiefen. Grundsätzlich gibt es zwei unterschiedliche Herangehensweisen: Das optimistische und das pessimistische Locking. Pessimistisches Locking wie Du es vorhast hat einen entscheidenden Nachteil: geht der Anwender in die Mittagspause, so sperrt er für diese Zeit den Datensatz (und ist sich dessen vielleicht nicht mal bewußt). Die Implementierung ist allerdings recht einfach. Es gibt beim SELECT die Option FOR UPDATE: SELECT ... FROM ... WHERE ... FOR UPDATE Damit sind die selektierten Datensätze bis zum Ende der Transaktion exclusiv gelockt. Die elegantere Methode ist das optimistische Locking. Hierzu fügst Du ein weiteres Feld in jde Tabelle ein, für die Du dies implementieren möchtest. Idealerweise ein Timestamp Feld, das auf ms Ebene anzeigt. Wird der Datensatz geladen, so selektierst Du das Feld und merkst dir den Wert im Programm. Speichert der Anwender seine Daten, so ergänzt Du Deinen Update wie folgt: UPDATE ... SET ...,dstimestamp=aktueller_timestamp WHERE id=... AND dstimestamp=der_vorher_gemerkte_wert Läuft der Update durch und ändert einen Datensatz, ist alles ok. Ändert der Update aber 0 Zeilen, dann wurde das Timestamp Feld schon von einer anderen Session geändert und dementsprechend dürfen diese Daten nicht ohne Rückmeldung überschrieben werden. Andere Möglichkeiten das sauber hinzubekommen gibt es nicht. Dim
  10. Es wird elegant, wenn Du Dir für jede Tabelle anhand der mysql Systemtabellen eine Historisierungstabelle generieren läßt (dazu muss man nur einmalig ein kleines Programm schreiben. Diese Tabelle sieht genauso aus und hat zusätzlich noch die von Dir benötigten Spalten. Für den Tabellennamen kannst Du z.B. den Prefix HIST o.ä. verwenden. Der zugehörige Trigger wird ebenfalls generiert. Evtl. musst Du noch eine Tabelle anlegen, in der Du ablegst für welche Tabellen Dein Generierungsprogramm die Objekte erzeugen soll falls Du Tabellen hast, die nicht davon betroffen sind. Damit hast Du eine vollautomatische Lösung, die Du bei jedem Build mitlaufen lassen kannst. Den Ansatz alles in einen BLOB zu konvertieren halet ich für nicht so optimal, denn, mal vom Performance Aspekt abgesehen, entfernst Du ohne Not die bereits vorhandene Struktur und überführst diese in ein strukturloses Format. Dim
  11. Hi, die XID ist eindeutig. Dim
  12. Noch als Ergänzung: Die PID sollte nur einmalig vorhanden sein und nicht in mehreren Tabellen gepflegt werden. Ansonsten müsste man auch den Rückweg abfangen (also Änderung der PID in KAUF). Und meine Meinung zum Thema Trigger dürfte hier bekannt sein Dim PS: Ein PK ist bereits NOT NULL das muss man nicht nochmal definieren.
  13. Hi, da ist schon mal das DB-Modell falsch. Ein Pk ist immutable - sprich er darf sich nicht ändern. Damit schließt sich die Verwendung eines fachlichen Werts als Pk, wie Du es getan hast, aus. Verwende als PK eine Nummer, die Du per Sequence füllst, so wie Du es auch schon in der Tabelle KAUF getan hast, ändere den entsprechenden FK-Constraint und fertig. Andere Lösungsmöglichkeiten sind technisch gesehen nicht korrekt. Dim
  14. Das ist aber nicht die Anforderung. Er möchte den nächst Größeren und nicht irgendeinen der größer ist. Rownum wird vor dem ORDER BY vergeben. Daher muss hier, wie schon beschrieben, mit einem Subselect gearbeitet werden. Wegen dem Index/Table Scan: Bevor ich hier wieder Pläne poste: Ist Dein Index jetzt mittlerweile schon ohne to_date, to_char oder was auch immer angelegt? Also ein simples create index xxx on tabelle (datum). Dim
  15. Doch natürlich. Voraussetzung für einen Indexzugriff sind folgende Punkte: 1. Der Datentyp stimmt überein bzw. die Konvertierungsrichtlinien von Oracle erlauben eine implicierte Konvertierung in den Datentyp des Index create table t( col1 number,col2 varchar2(10),col3 varchar2(10)); create index t_ix1 on t (col1); create index t_ix2 on t (col2); create index t_ix3 on t (upper(col3)); insert into t select rownum,rownum,rownum from all_objects where rownum <=10000 ; commit; begin dbms_stats.gather_table_stats(ownname=>'DIMITRI',tabname=>'T'); end; / Jetzt ein paar Abfragen: explain plan for select * from t where col1='123'; select * from table(dbms_xplan.display); | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 14 | 2 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID| T | 1 | 14 | 2 (0)| 00:00:01 | |* 2 | INDEX RANGE SCAN | T_IX1 | 1 | | 1 (0)| 00:00:01 | ------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("COL1"=123) Beachte die Zeile mit der access Angabe. Da Oracle bei Vergleichen zwischen Strings und Zahlen in Zahlen konvertiert, kann der Index verwendet werden. Schreibst Du statt '123' ein '123a' wird die Abfrage zwar gestartet, aber Du bekommst natürlich einen Fehler, weil '123a' nicht in eine gütige Zahl umgewandelt werden kann. Jetzt das nächste Beispiel: explain plan for select * from t where col2=123; -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 14 | 9 (0)| 00:00:01 | |* 1 | TABLE ACCESS FULL| T | 1 | 14 | 9 (0)| 00:00:01 | -------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter(TO_NUMBER("COL2")=123) Obwohl auf der Spalte col2 ein Index sitzt, kann er nicht verwendet werden, da Oracle wie oben in Zahlen konvertiert. Da ein Index für einen String eine komplett andere Sortierung als für eine Zahl besitzt, kann er hier auch nicht verwendet werden und Oracle durchsucht die komplette Tabelle. Zu guter letzt der Function Based Index auf die Spalte col3: explain plan for select * from t where col3='123'; select * from table(dbms_xplan.display); -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 14 | 9 (0)| 00:00:01 | |* 1 | TABLE ACCESS FULL| T | 1 | 14 | 9 (0)| 00:00:01 | -------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("COL3"='123')Bei einem FBI muss die WHERE Bedingung immer auch den genauen Funktionsaufruf beinhalten. Eine UPPER('123') würde den Index also verwenden. Die Konvertierungsrichtlinien von Oracle findest Du hier Einen FBI sollte man nur verwenden, wenn es wirklich sinvoll ist. Bei einem DATE würde mit kein Fall einfallen bei dem das so wäre. Ich vermute, dass Deine Probleme z.T. auch daher kommen. 2. Die Ergebnismenge darf nicht zu groß sein Ein Indexzugriff ist nur dann sinnvoll, wenn die Ergebnissmenge nicht zu groß wird. Wie groß die Menge sein darf variiert und hängt von vielen Faktoren ab, die der CBO in seine Berechnungen mit einbezieht. Als Fausregel gilt, dass bei kleinen Tabellen bis ca. 10%, bei sehr großen Tabellen (Millionen von Einträgen) bis ca. 20-30% der Ergebnismenge ein Indexzugriff verwendet wird. Wie gesagt nur als Fausregel und es gibt sehr viele Parameter, die das beeinflussen. 3. Die Statistiken müssen aktuell sein Damit der CBO seine Formeln richtig anwenden kann, müssen die Tabellen über aktuelle Statistiken verfügen. DBMS_STATS wurde ja schon erwähnt. 4. Das SQL muss "verständlich" sein. SQL ist eine sehr redundante Sprache, dementsprechend gibt es auch viele Möglichkeiten etwas auszudrücken. Je präziser man das macht desto eher hat der CBO eine Chance zu verstehen, was man genau machen möchte. 5. Die Tabelle spiegelt die Daten wieder. Je genauer die Tabellendefinition zu den Daten passt, desto besser kann der CBO seine Entscheidungen abwägen. Darf eine Spalte keine NULL Werte enthalten, setze ich einen NOT NULL Constraint, ist eine Spalte Unique, dann verwende ich auch einen Unqiue Index, enthält eine Spalte ein Datum verwende ich ein DATE usw. usw. Um ein sortiertes Ergebnis zu bekommen muss man ORDER BY verwenden. Oracle wird intern natürlich die Sortierung eines Index verwenden falls möglich, aber ohne ORDER BY hast Du keine Gewährleistung wie das Ergebnis letztendlich sortiert wird (auch wenn es jetzt vielleicht passen sollte). Und last but not least: Full Table Scans sind nicht immer langsamer als ein Indexzugriff. Falls Oracle also den Index nicht verwendet, kann es durchaus sein, dass ein Indexzugriff langsamer wäre. Umgekehrt ist auch der CBO nicht perfekt und macht Fehler. Sofern die obigen Punkte alle erfüllt sind, kann es in Einzelfällen durchaus sein, dass man ihm mit einem Hint auf die Sprünge helfen muss Dim
  16. Heißt das, dass ihr das Datum in einem VARCHAR2 Feld speichert? Falls ja, solltet ihr ein DATE verwenden und einen normalen (also keinen Function based Index) Index anlegen. Gross-/Kleinschreibung sollte bei einem Datum ja nicht relevant sein. Schon, aber keiner, mit dem auch der Index verwendet wird. Im Index stehts nun mal so drinnen und so ist er auch sortiert. Dim
  17. Also wenn der Index wirklich als Function Based Index mit dieser Definition angelegt wurde, dann erklärt das ja einiges. Durch das to_char wird aus dem Datum ein String, damit Funktioniert auch die Datumsarithetik natürlich nicht mehr. Leg den index einfach wie folgt an: CREATE INDEX index_name ON tabelle (datumsfeld) Fertig. to_char sollte wirklich nur zur Formatierung in der Ausgabe verwendet werden. Dim PS: Ich gehe davon aus, dass das Datumsfeld in der Datenbank auch wirklich als DATE definiert ist.
  18. Sind die Tabellen und der Index mit dbms_stats analysiert? Wenn Du schon eine vereinfachte Variante gepostet hast, sind denn in der echten Abfrage noch weitere Bedingungen, joins etc. drinnen? Wie ist der Index definiert? Dim
  19. Hi, zum einen sollte man immer to_date verwenden wenn man mit Datumswerten arbeitet, denn der 12.03.2010 könnte auch der 3 Dezember sein je nachdem welche Ländereinstellung auf dem Client gesetzt ist. Des weiteren liefert Deine Abfrage irgendein Datum das größer ist als dein angegegebenes bzw. besser ausgedrückt es liefert alle Datensätze die ein größeres Datum besitzen. Was Du möchtest geht so: SELECT * FROM (SELECT datum FROM tabelle WHERE datum >to_date('01.01.2010','DD.MM.YYYY') ORDER BY datum DESC) a WHERE ROWNUM=1Beachte auch, dass ein Datum in Oracle immer auch eine Uhrzeit beinhaltet. 01.01.2010 wird also intern zu einem 01.01.2010 00:00. Dim
  20. Du solltest ein ResultSet dann schließen, wenn Du es nicht mehr brauchst. Damit gibst Du die Resourcen frei und musst Dir keine Gedanken mehr darüber machen. Dim
  21. Reputationen sind mir relativ egal. Was ich aus seinem Lebenslauf herauslese, war er nie, vielleicht mal von einem Praktikum abgesehen, längere Zeit in der Verantwortung für ein echtes, produktives System. Lehramtler in Passau (keine 60km von mir) zu unterrichten, dürfte dieses Gap kaum geschlossen haben. Ich habe die letzten 10 Jahre Erfahrungen als Azubi, Entwickler sowie seit 2 Jahren als technisch Verantwortlicher für ein System, das ca. 10 Tsd User täglich zuverlässig und performant mit Daten zu versorgen hat. Das schließt Datenlieferungen vom Mainframe ebenso ein wie Rücklieferungen aus der dezentralen Welt. Im dezentralen Bereich laufen Programme von mir, die die lokale Oracle Datenbanken innerhalb einer Agentur (je nach dem, bei welcher Versicherung Du bist hast Du evtl. auch schon mal die Anwendung gesehen, die auf diese Datenbank zugreift) quasi in Echtzeit miteinander abgleichen und konsistent halten bzw. auch ohne Probleme damit zurecht kommen, wenn ein Agent sein NB aus der Docking Station nimmt und sich später per UMST wieder einwählt. Die Oracle Replikation war uns zu starr, darum hab ich da was flexibleres geschrieben Konstrukte, wie Du sie hier vorschlägt würden keine 10 Minuten in der Entwicklungsdatenbank überleben bevor ich mir den Kollegen greife - sofern er überhaupt auf die Idee kommt sowas zu machen. Die jenigen Autoren, von denen ich mir Wissen erarbeitet habe sind weniger durch eine Aufzählung erworbene Titel als vielmehr durch jahrelange Erfahrung zu den anerkannten Know How Trägern im Datenbankbereich (insb. Oracle) geworden. Dazu gehören Tom Kyte (vgl. Signatur), Jonathan Lewis, Wolfgang Breitling, Carry Millsap uvm., die Du über diese Links erreichen kannst. Ob Kemper hier einfach nur Müll schreibt, oder Du ihn falsch auslegst vermag ich nicht 100%ig zu sagen - Dein Zitat spricht jedenfalls im Bereich Trigger und Konsistenz nicht dafür, dass er tiefgreifende Erfahrung damit hat, große Systeme zu designen, die pro Tag 10 Mio und mehr Änderungen verkraften müssen ohne das ein falsch geschriebener Trigger innerhalb von Tagen oder Wochen die Daten in ihre Einzelteile zerlegt. Dim
  22. Sofern Du immer nur eine Transaktion zu einer Zeit ausführst ja - aber Datenbanken wurden nicht gemacht um die Zugriffe auf eine Ressource künstlich zu serialisieren. Sofern wir von einem Multiusersystem sprechen, müssen wir also immer davon ausgehen, dass mehrere Transaktionen gleichzeitig versuchen auf das Zimmer einen sich überschneidenden Zeitrum zu buchen. Da Transaktionsänderungen für andere Sessions frühestens dann sichtbar werden, wenn die ändernde Transaktion sie comittet hat (Dirty Reads lassen wir mal außen vor, sofern vom DBMS überhaupt unterstützt, denn wer die verwenden muss hat eh schon verloren) können wir in einem Trigger nie sicher sein, ob nicht ein Stand gelesen wird, der gerade verändert wird aber noch nicht comittet ist. Transaktion Tx1 startet zum Zeitpunkt T1 und prüft, ob eine Buchung für den Zeitraum Z vorhanden ist. Da dies nicht der Fall ist, schreibt Tx1 zum Zeitpunkt T1+x die Änderung fest. Zum Zeitpunkt T2 startet die Transaktion Tx2 innerhalb einer anderen Session, wobei gilt T1 > T2 < T1+x. Zum Zeitpunkt T2+y für den gilt T2+y < T1+x prüft Tx2 ebenfalls, ob eine Buchung vorhanden ist. Da Tx1 noch nicht comittet hat, sieht Tx2 diesen Eintrag nicht und comittet ebenfalls zu einem Zeitpunkt T2+y+z. Damit haben wir eine klassische Doppelbuchung. Ja, dass hatten wir schon mal. Aber wer einen Trigger als allgemeinen Konsistenzmechanismus beschreibt, sollte sich doch nochmal eingehend mit der Thematik befassen. Es gibt in einer DB genau 2 (in Worten zwei) Mechanismen, die verwendet werden können um die technische und fachliche Konsistenz sicherzustellen. Das eine sind Constraints, das andere sind Locks. Es ist nicht möglich mit Triggern einen wie auch immer gearteten Constraint nachzubauen (ok, einen Check Constraint schon) ohne den Zugriff auf die Ressource (== Tabelle) zu serialisieren. Trigger sollten nur dann benutzt werden, wenn es nicht anders geht. Sie sind langsam, agieren ausserhalb der normalen Programmlogik und wer nicht weiß wie man sie richtig verwendet (dazu zähle ich auch die von Dir zitierten Herren), der läuft Gefahr seine Daten fachlich und ggf. auch technisch inkonsistent werden zu lassen. Dim
  23. Die PG Techniken sind mir nicht bekannt, aber die Triggerlösung ist definitiv nicht multiuserfähig, da unterschiedliche Sessions die uncomitteten Einträge der anderen nicht sehen können und es daher früher oder später zu Überbuchungen kommt. Ich würde hier wie folgt vorgehen: Angeommen, es gibt eine Tabelle ZIMMER, wird bei jedem Buchungsversuch der entsprechende Eintrag in dieser Tabelle mittels SELECT ... FOR UPDATE gelockt. Jetzt hat man dieses Zimmer im exclusiven Zugriff und kann seine Buchungsdaten speichern. Eine andere Session würde jetzt erstmal warten, bis der neue Eintrag comittet ist, den Datensatz wieder sperren, evtl. feststellen, dass der vorher noch als frei angezeigte Zeitraum mittlerweile belegt ist und mit einer entsprechenden Meldung abbrechen. Das ganze wird natürlich optimistisch gelockt, sprich der Lock auf das Zimmer erfolgt erst, wenn über die Anwendung die Daten schon fix und fertig eingegeben sind und der Anwender auf Speichern klickt. Man könnte es auch noch eleganter machen, und in der Tabelle ZIMMER einen Änderungszähler hinterlegen, der jedesmal hochgezählt wird, wenn eine Buchung erfolgt. Ist der Änderungszähler, der während des erstmaligen Ladens des Zimmers für die Anzeige in der AW gelesen wurde, identisch mit dem Zähler der beim Locken in der Tabelle steht, muss ich keine vorherige Prüfung laufen lassen, ob der Zeitraum noch frei ist und spare mir damit etwas Zeit und CPU. Und im übrigen: Keine Anwendungslogik in Triggern hinterlegen :mod: Dim
  24. Und was passiert, wenn während eine Abfrage läuft eine weitere Session diese Abfrage startet und die View neuanlegen möchte? Mutiuserfähig ist das auf jeden Fall nicht - davon mal davon abgesehen, dass man es einfach nicht so macht. Warum wird nicht einfach ein normales Select verwendet? Dim
  25. Der Ansatz ist ein bissl verquer. Wieso legst Du die View nicht einmalig an und schränkst dann nur über die WHERE Abfrage ein? Fertig. Falls das ganze komplett in PL/SQL laufen soll, wäre auch noch die Möglichkeit das Ergebnis als REF CURSOR zurückzugeben. Im aufrufenden Programm bekommt man das als ResultSet, RecordSet oder wie immer man es in der jeweiligen Sprache auch nennt zurück. Das ganze würde dann wie folgt aussehen: CREATE OR REPLACE FUNCTION STAMMDATEN_bearbeiten (p_id VARCHAR2) RETURN SYS_REFCURSOR IS l_retVal SYS_REFCURSOR; BEGIN OPEN l_retVal FOR 'SELECT * FROM tabelle WHERE id=:1' USING p_id; RETURN l_retVal; END;Damit lieferst Du die Ergebnismenge bzw. besser gesagt einen Zeiger darauf, an den Aurufer zurück. Wie das dann konkret im Programm aussieht ist je nach Sprache etwas anders, aber dafür gibt es dann die Doku. Dim PS: Wieso heißt es stammdaten_bearbeiten wenn das Ergebnis einer Abfrage zurückgegeben wird?

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...