Ottenere un recordset da una Function PL/SQL

 This article is available in english language too.

Tempo fa sono incappato in un problema con Oracle. Come ottenere un recordset da una query parametrica in PL/SQL in un solo comando?

Le prime risposte cui si potrebbe pensare sono:

  • Uso una vista a cui passo un paramtero: non si possono passare parametri ad una vista; una vista potrebbe al massimo leggere un parametro dal SYS_CONTEXT o da una tabella di appoggio, ma in questo modo non si riuscirebbe in un solo comando ad ottenere il risultato
  • Uso una procedure; una procedure non può restituire un recordset; l’unico oggetto simile che può restituire è un cursore, che più che essere “visualizzato” dovrebbe essere poi utilizzato da una qualche altra procedura (PL/SQL o client che sia)
La tipologia di oggetto che risolve questo specifico problema è l’uso degli OBJECT TYPES e delle FUNCTION PIPELINED.
Una funzione pipelined può restituire una collezione di oggetti ognuno dei quali verrà restituito come un record nel recordset risultante; per definire un nuovo oggetto e la relativa collezione in PL/SQL avremo:
    CREATE OR REPLACE
    TYPE O_MY_OBJECT AS OBJECT (
      MY_DATE                       DATE
    , MY_NUMBER                     NUMBER
    , MY_VARCHAR                    VARCHAR2(20)
    );

    CREATE OR REPLACE
    TYPE T_MY_OBJECT AS TABLE OF O_MY_OBJECT;
Quindi, una volta definiti questi due tipi, si può dichiarare una funzione PIPELINED che restituisca il tipo collezione e nel suo body creare gli oggetti (i record) e mandarli in output con l’istruzione PIPE ROW():
    FUNCTION MY_FUNCTION(V_MY_PARAM IN VARCHAR2)
      RETURN  T_MY_OBJECT
      PIPELINED
    AS
    V_MY_OBJ_VAR O_MY_OBJECT := O_MY_OBJECT(null, null, null);
    BEGIN
          SELECT
                SYSDATE
              , 10
              , 'CIAO MONDO! -> ' || V_MY_PARAM
          INTO
              V_MY_OBJ_VAR.MY_DATE
            , V_MY_OBJ_VAR.MY_NUMBER
            , V_MY_OBJ_VAR.MY_VARCHAR
          FROM
              DUAL;

          PIPE ROW(V_MY_OBJ_VAR);

      RETURN;
    END MY_FUNCTION;
Vediamo i particolari della funzione:
  • V_MY_OBJ_VAR O_MY_OBJECT := O_MY_OBJECT(null, null, null); => Definisco una variabile e la inizializzo con il costruttore dell’oggetto
  • Parte INTO => inserisco i valori desiderati (in questo caso delle costanti) nelle proprietà del mio oggetto
  • PIPE ROW(V_MY_OBJ_VAR) => mando in output al recordset il mio oggetto
Per avere righe che vengono da una query parametrica, è sufficiente costruire un cursore e in un LOOP costruire le istanze di oggetti di cui si farà il PIPE ROW.
Infine per richiamare la funzione così costruita ed avere il risultato finale, è necessario utilizzare la funzione TABLE di PL/SQL:
     SELECT * FROM TABLE(MY_FUNCTION('SAMPLE VALUE'));
Il risultato, sarà una griglia in tutto e per tutto utilizzabile come una tabella, o una vista.

LightBox per visualizzare un DIV azionato da script

 This article is available in english language too.

Usare il componente Lightbox per visualizzare il contenuto di un DIV anziché un immagine può non essere così immediato.
Per ottenere l’effetto desiderato nel mio esempio ho usato il plugin scsLightbox per jQuery. Questo facilita l’interazione con gli elementi della pagina.
Ecco le istruzioni sintetiche:

  1. Scaricare jQuery e il plugin scsLightbox
  2. Caricare nella propria pagina gli script di jQuery della versione desiderata (io l’ho testato con 1.4.2 e 1.5.2) e quello del plugin, più il CSS del plugin:
<script type="text/javascript"
     src="MyScripts/jquery/jquery-x.y.z.min.js"></script>
<script type="text/javascript"
     src="MyScripts/scsLightbox/jquery.scslightbox.js"></script>
<link rel="stylesheet" type="text/css" 
     href="MyStyles/scsLightbox/jquery.scslightbox.css">
  1. Dato che l’evento che attiva la lightbox è il click di un link, è necessario inserire un link, che attiveremo da JS e il DIV di cui vogliamo visualizzare il contenuto nel LightBox; tale link sarà vuoto se non ci interessa che sia cliccabile col mouse (lo attiveremo da JS):
<a id="link-content-div" href="#content-div"></a>
<div id="content-div" style="display: none;">
  Il contenuto del nostro div.
</div>
Inizialmente il div è nascosto. Da notare che l’attributo href del link punta al selettore del div; questo è lo stesso che verrebbe utilizzato in un CSS per individuare il div.
  1. A questo punto, bisogna attivare la visualizzazione del content-div nel LightBox e definire la funzione JS che può essere richiamata per attivare il LighBox. Per trovare gli elementi del DOM e attivare il link usiamo la sintassi di jQuery:
<script type="text/javascript">
  $(function() {
    $('#link-content-div').scsLightbox();
  });
  function ShowContentDiv() {
    $('#link-content-div').trigger('click');
  }
</script>

Il meccanismo è abbastanza semplice e abbastanza utile dato che, a differenza del solo LightBox che consente la visualizzazione di sole immagini linkate dal tag a, qui visualizziamo nel LightBox il contenuto del div, quindi qualsiasi frammento HTML e inoltre lo attiviamo da script, quindi all’accadere di qualunque evento gestito sul client.

Riferimenti: