Ich habe eine PL/SQL-Funktion mit BOOLEAN im Parameter:
function get_something(name in varchar2, ignore_notfound in boolean);
Diese Funktion ist Teil eines Drittanbieter-Tools. Ich kann dies nicht ändern.
Ich möchte diese Funktion in einer SELECT-Anweisung wie folgt verwenden:
select get_something('NAME', TRUE) from dual;
Das funktioniert nicht, ich bekomme diese Ausnahme:
ORA-00904: "TRUE": Ungültige Kennung
Nach meinem Verständnis wird das Keyword TRUE
nicht erkannt.
Wie kann ich diese Arbeit machen?
Sie können eine Wrapper-Funktion wie folgt erstellen:
function get_something(name in varchar2,
ignore_notfound in varchar2) return varchar2
is
begin
return get_something (name, (upper(ignore_notfound) = 'TRUE') );
end;
dann ruf an:
select get_something('NAME', 'TRUE') from dual;
Es liegt an Ihnen, was die gültigen Werte von ignore_notfound in Ihrer Version sind. Ich habe angenommen, dass TRUE TRUE bedeutet und alles andere FALSE.
Sie können auf jeden Fall einen booleschen Wert von einer SELECT-Abfrage erhalten. Sie können einfach keinen booleschen Datentyp verwenden.
Sie können einen Boolean mit 1/0 darstellen.
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
Gibt 1 zurück (in Hibernate/Mybatis/etc ist 1 wahr). Andernfalls können Sie von einem SELECT druckbare boolesche Werte erhalten.
SELECT CASE WHEN (10 > 0) THEN 'true' ELSE 'false' END AS MY_BOOLEAN_COLUMN
FROM DUAL
Dies gibt den String 'true'
zurück.
Aus Dokumentation :
Sie können die Werte
TRUE
undFALSE
nicht in eine Datenbankspalte einfügen. Sie können keine Spaltenwerte in einer VariablenBOOLEAN
auswählen oder abrufen. Funktionen, die von einerSQL
-Abfrage aufgerufen werden, können keineBOOLEAN
-Parameter annehmen. Es können auch keineSQL
-Funktionen wieTO_CHAR
eingebaut werden. UmBOOLEAN
-Werte in der Ausgabe darzustellen, müssen SieIF-THEN
- oderCASE
-Konstrukte verwenden, umBOOLEAN
-Werte in einen anderen Typ zu konvertieren, wie0
oder1
,'Y'
oder'N'
,'true'
oder'false'
usw.
Sie müssen eine Wrapper-Funktion erstellen, die einen SQL
-Datentyp verwendet, und ihn stattdessen verwenden.
Der BOOLEAN-Datentyp sind PL/SQL-Daten Art. Oracle bietet kein gleichwertiger SQL-Datentyp (...) können Sie Erstellen Sie eine Wrapper-Funktion, die eine SQL-Typ zum BOOLEAN-Typ.
Überprüfen Sie dies: 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;
Kompilieren Sie dies in Ihrer Datenbank und beginnen Sie mit der Verwendung von booleschen Anweisungen in Ihren Abfragen.
anmerkung: Die Funktion get ist ein varchar2-Parameter. Stellen Sie daher sicher, dass alle "Zeichenfolgen" in Ihrer Anweisung eingeschlossen werden. Es wird 1 für wahr und 0 für falsch zurückgegeben.
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;
/
Die Antwort auf diese Frage lautet einfach: Verwenden Sie BOOLEAN nicht mit Oracle - PL/SQL ist dumm und funktioniert nicht. Verwenden Sie einen anderen Datentyp, um den Prozess auszuführen.
Ein Hinweis für SSRS-Berichtsentwickler mit Oracle-Datenquelle: Sie können BOOLEAN-Parameter verwenden, seien Sie jedoch vorsichtig bei der Implementierung. Oracle PL/SQL kann mit BOOLEAN nicht einwandfrei abgespielt werden. Sie können jedoch den BOOLEAN-Wert im Tablix-Filter verwenden, wenn sich die Daten in Ihrem Dataset befinden. Das hat mich wirklich gestört, weil ich den BOOLEAN-Parameter mit der Oracle-Datenquelle verwendet habe. In diesem Fall habe ich jedoch nach Tablix-Daten und nicht nach SQL-Abfragen gefiltert.
Wenn sich die Daten NICHT in Ihren SSRS-Datensatzfeldern befinden, können Sie die SQL mit einem INTEGER-Parameter wie folgt umschreiben:
__
<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' )
Wenn sich die Daten in Ihren SSRS-Datensatzfeldern befinden, können Sie einen Tablix-Filter mit einem BOOLEAN-Parameter verwenden:
__
</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>
In Oracle 12 können Sie die Klausel WITH
verwenden, um Ihre Hilfsfunktionen zu deklarieren. Ich gehe davon aus, dass Ihre get_something
-Funktion varchar2
zurückgibt:
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;
Natürlich hätten Sie Ihre Hilfsfunktion auch irgendwo im Schema wie in dieser Antwort gezeigt speichern können, aber mit WITH
haben Sie keine externen Abhängigkeiten, nur um diese Abfrage auszuführen. Ich habe hier ausführlicher über diese Technik gebloggt .