J'ai une fonction PL/SQL avec BOOLEAN en paramètre:
function get_something(name in varchar2, ignore_notfound in boolean);
Cette fonction fait partie de l'outil tiers, je ne peux pas le changer.
Je voudrais utiliser cette fonction dans une instruction SELECT comme ceci:
select get_something('NAME', TRUE) from dual;
Cela ne fonctionne pas, je reçois cette exception:
ORA-00904: "TRUE": identificateur non valide
Si je comprends bien, le mot clé TRUE
n'est pas reconnu.
Comment puis-je faire ce travail?
Vous pouvez créer une fonction wrapper comme ceci:
function get_something(name in varchar2,
ignore_notfound in varchar2) return varchar2
is
begin
return get_something (name, (upper(ignore_notfound) = 'TRUE') );
end;
puis appelez:
select get_something('NAME', 'TRUE') from dual;
C’est à vous de choisir les valeurs valides de ignore_notfound dans votre version. J’ai donc supposé que «VRAI» signifiait VRAI et que tout le reste était FAUX.
Vous pouvez certainement obtenir une valeur booléenne à partir d'une requête SELECT, vous ne pouvez tout simplement pas utiliser un type de données booléen.
Vous pouvez représenter un booléen avec 1/0.
CASE WHEN (10 > 0) THEN 1 ELSE 0 END (It can be used in SELECT QUERY)
SELECT CASE WHEN (10 > 0) THEN 1 ELSE 0 END AS MY_BOOLEAN_COLUMN
FROM DUAL
Returns, 1 (dans Hibernate/Mybatis/etc 1 est vrai). Sinon, vous pouvez obtenir des valeurs booléennes imprimables à partir d'un SELECT.
SELECT CASE WHEN (10 > 0) THEN 'true' ELSE 'false' END AS MY_BOOLEAN_COLUMN
FROM DUAL
Ceci retourne la chaîne 'true'
.
De documentation :
Vous ne pouvez pas insérer les valeurs
TRUE
etFALSE
dans une colonne de base de données. Vous ne pouvez pas sélectionner ou extraire les valeurs de colonne dans une variableBOOLEAN
. Les fonctions appelées à partir d'une requêteSQL
ne peuvent prendre aucun paramètreBOOLEAN
. Aucune des deux ne peut intégrer les fonctionsSQL
telles queTO_CHAR
; pour représenter les valeursBOOLEAN
en sortie, vous devez utiliser les constructionsIF-THEN
ouCASE
pour traduire les valeursBOOLEAN
en un autre type, tel que0
ou1
,'Y'
ou'N'
,'true'
ou'false'
, etc.
Vous devrez créer une fonction wrapper prenant un type de données SQL
et l'utiliser à la place.
Le type de données BOOLEAN est une donnée PL/SQL type. Oracle ne fournit pas de type de données SQL équivalent (...) vous pouvez créer une fonction wrapper qui mappe un Type SQL au type BOOLEAN.
Vérifiez ceci: http://forums.datadirect.com/ddforums/thread.jspa?threadID=1771&tstart=0&messageID=5284
select get_something('NAME', sys.diutil.int_to_bool(1)) from dual;
Compilez cela dans votre base de données et commencez à utiliser des instructions booléennes dans vos requêtes.
remarque: la fonction get est un paramètre varchar2, veillez donc à envelopper toutes les "chaînes" de votre instruction. Il retournera 1 pour vrai et 0 pour faux;
select bool('''abc''<''bfg''') from dual;
CREATE OR REPLACE function bool(p_str in varchar2) return varchar2
is
begin
execute immediate ' begin if '||P_str||' then
:v_res := 1;
else
:v_res := 0;
end if; end;' using out v_res;
return v_res;
exception
when others then
return '"'||p_str||'" is not a boolean expr.';
end;
/
La réponse à cette question est simple: n'utilisez pas BOOLEAN avec Oracle - PL/SQL est stupide et cela ne fonctionne pas. Utilisez un autre type de données pour exécuter votre processus.
Remarque à l'attention des développeurs de rapports SSRS avec la source de données Oracle: Vous pouvez utiliser les paramètres BOOLEAN, mais soyez prudent lors de la mise en œuvre. Oracle PL/SQL ne fonctionne pas bien avec BOOLEAN, mais vous pouvez utiliser la valeur BOOLEAN dans le filtre de tableau matriciel si les données résident dans votre ensemble de données. Cela m'a vraiment fait trébucher, car j'ai utilisé le paramètre BOOLEAN avec la source de données Oracle. Mais dans ce cas, je filtrais sur des données de tableau matriciel, pas sur une requête SQL.
Si les données ne figurent PAS dans vos champs de jeu de données SSRS, vous pouvez réécrire le code SQL à l’aide d’un paramètre INTEGER:
__
<ReportParameter Name="paramPickupOrders">
<DataType>Integer</DataType>
<DefaultValue>
<Values>
<Value>0</Value>
</Values>
</DefaultValue>
<Prompt>Pickup orders?</Prompt>
<ValidValues>
<ParameterValues>
<ParameterValue>
<Value>0</Value>
<Label>NO</Label>
</ParameterValue>
<ParameterValue>
<Value>1</Value>
<Label>YES</Label>
</ParameterValue>
</ParameterValues>
</ValidValues>
</ReportParameter>
...
<Query>
<DataSourceName>Gmenu</DataSourceName>
<QueryParameters>
<QueryParameter Name=":paramPickupOrders">
<Value>=Parameters!paramPickupOrders.Value</Value>
</QueryParameter>
<CommandText>
where
(:paramPickupOrders = 0 AND ordh.PICKUP_FLAG = 'N'
OR :paramPickupOrders = 1 AND ordh.PICKUP_FLAG = 'Y' )
Si les données se trouvent dans vos champs de jeu de données SSRS, vous pouvez utiliser un filtre de tableau matriciel avec un paramètre BOOLEAN:
__
</ReportParameter>
<ReportParameter Name="paramFilterOrdersWithNoLoad">
<DataType>Boolean</DataType>
<DefaultValue>
<Values>
<Value>false</Value>
</Values>
</DefaultValue>
<Prompt>Only orders with no load?</Prompt>
</ReportParameter>
...
<Tablix Name="tablix_dsMyData">
<Filters>
<Filter>
<FilterExpression>
=(Parameters!paramFilterOrdersWithNoLoad.Value=false)
or (Parameters!paramFilterOrdersWithNoLoad.Value=true and Fields!LOADNUMBER.Value=0)
</FilterExpression>
<Operator>Equal</Operator>
<FilterValues>
<FilterValue DataType="Boolean">=true</FilterValue>
</FilterValues>
</Filter>
</Filters>
Avec Oracle 12, vous pouvez utiliser la clause WITH
pour déclarer vos fonctions auxiliaires. Je suppose que votre fonction get_something
renvoie varchar2
:
with
function get_something_(name varchar2, ignore_notfound number)
return varchar2
is
begin
-- Actual function call here
return get_something(name, not ignore_notfound = 0);
end get_something_;
-- Call auxiliary function instead of actual function
select get_something_('NAME', 1) from dual;
Bien sûr, vous auriez aussi pu stocker votre fonction auxiliaire quelque part dans le schéma comme le montre cette réponse , mais en utilisant WITH
, vous n’avez aucune dépendance externe pour exécuter cette requête. J'ai blogué sur cette technique plus en détail ici .