web-dev-qa-db-fra.com

Comment utiliser le type BOOLEAN dans une instruction SELECT

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?

46
Ula Krukar

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.

26
Tony Andrews

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'.

44
Ash

De documentation :

Vous ne pouvez pas insérer les valeurs TRUE et FALSE dans une colonne de base de données. Vous ne pouvez pas sélectionner ou extraire les valeurs de colonne dans une variable BOOLEAN. Les fonctions appelées à partir d'une requête SQL ne peuvent prendre aucun paramètre BOOLEAN. Aucune des deux ne peut intégrer les fonctions SQL telles que TO_CHAR; pour représenter les valeurs BOOLEAN en sortie, vous devez utiliser les constructions IF-THEN ou CASE pour traduire les valeurs BOOLEAN en un autre type, tel que 0 ou 1, '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.

19
Quassnoi

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

5
JuanZe
select get_something('NAME', sys.diutil.int_to_bool(1)) from dual;
2
Kanu Mundu

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;
/
2
Eran ben-ari

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>
0

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 .

0
Lukas Eder