Je cherche la manière optimale de créer une fonction qui ne peut accepter aucun paramètre et renvoyer tous les résultats, mais accepte également les paramètres et renvoyer ces résultats.
La norme que j'ai traitée à mon travail est-ce : p> Le problème est que je souhaite retourner des enregistrements ayant également un type de NULL, et en utilisant: p>
5 Réponses :
Dès le haut de ma tête, je devinerais l'utilisation du mot clé code> par défaut code> ferait l'affaire, n'est-ce pas? (Le lien suivant donnera quelques détails supplémentaires.)
Le : = code> dans les déclarations de paramètres est identique à celui
par défaut code>. Le problème semble être qu'une valeur nulle pour le paramètre signifie correspondre aux enregistrements avec une valeur null dans la colonne correspondante; Donc, quelle valeur par défaut doit être utilisée pour indiquer "tous les enregistrements"?
Ne retourne pas les enregistrements qui ont également un type de null. Je veux essentiellement égaler le type si je fournis le paramètre, sinon n'utilise pas le paramètre. Ce n'est pas dynamique SQL, vous pouvez donc voir le dilemna. Si c'était le cas, je n'exclureais pas la clause.
@Dave Costa: Merci pour l'information. J'ai toujours utilisé le mot-clé code> par défaut code>, et non le signe égal (: = code>) pour définir les valeurs par défaut.
@jlrolin: Puissiez-vous fournir un exemple de code de votre corps de fonction, avec un exemple de données dans la table de données que vous extrayez les données? Cela pourrait faire ressortir d'autres idées de solutions.
@Will: Le corps de la fonction est un simple sélectionnel * à partir de la table où Type = NVL (i_type, type), étant introduit dans un ref_cursor, puis retourné.
@jlrolin: et l'échantillon de la table de données?
Deux champs: code et type. Le code n'est jamais NULL, VARCHAR2 (2 octets), type peut être NULL, VARCHAR2 (5 octets).
Pour réitérer ma compréhension du problème: vous ne pouvez pas prendre la valeur par défaut de Une possibilité est d'ajouter un paramètre booléen correspondant à chaque paramètre de recherche, ce qui indique s'il devrait être utilisé pour filtrer les résultats. Un problème potentiel avec ceci est qu'un appelant pourrait spécifier une valeur de recherche mais ne pas définir le drapeau sur true, produisant des résultats inattendus. Vous pouvez vous protéger contre cela au moment de l'exécution en soulevant une exception si le drapeau est faux pour toute valeur de recherche autre que Une autre possibilité est de définir une valeur hors du domaine pour chaque colonne de recherche - par exemple. Si la chaîne 'tout' est transmise pour le paramètre, il ne filtrera pas les valeurs de cette colonne. Cela devrait fonctionner bien tant que vous pouvez trouver une valeur sensitaire valable pour chaque colonne. Je suggérerais de déclarer les valeurs sentinelles en tant que constantes de certains packages, afin que les appels à la fonction puissent ressembler à null code> pour signifier "renvoyer tous les enregistrements", car le comportement attendu actuel est qu'il ne renverra que ces enregistrements où La valeur est en réalité null. p>
null code>. P>
get_records (pkg.all_codes, "type1") p>. P>.
Pourquoi pas simplement ce que vous avez avec l'ajout de de cette façon, lorsque le paramètre transmis est null, il cherche tout (y compris les nulls) ou la valeur spécifiée. Maintenant, si vous voulez juste que les nulls ... p> exemple (modifiez la valeur de NULL en 5 et vous verrez la sortie) p> DATAID
----------------------
6
Je suggérerais de le changer à type = i_type ou i_type est null code>. C'est dans mon expérience plus susceptible de tirer parti d'un index sur
type code> que d'utiliser NVL (). Aussi, semble plus claire pour moi.
@Dave: C'est la solution que j'ai mise en œuvre.
Cette approche n'est généralement pas sargable
Le moyen standard de résoudre ce problème est de surcharger la fonction, au lieu d'utiliser des valeurs par défaut: Remarque: Si vous avez également besoin d'une version i_type code> par elle-même, vous aurez peut-être des problèmes si cela a le même type sous-jacent que
i_code code> - auquel cas vous auriez besoin d'utiliser un nom différent pour la fonction. P> P>
@OMG: Eh bien, ma solution ne dit rien de savoir si Dynamic SQL est utilisé ou non - le point est, comment dites-vous entre Get_Records (NULL, NULL) et GET_RECORDS (NULL), à moins que vous ne composiez de "valeurs magiques" pour le Paramètres par défaut? La surcharge est la meilleure façon de résoudre ce problème, imo.
J'ai utilisé le piratage suivant (en supposant que p_product est une entrée de procédure facultative):
procedure get_data(p_product in number := null)
...
select *
from tbl t
where t.product = decode(p_product, null, t.product, p_product);
...