0

インラインIFをシミュレートするために、Oracle 9i(バージョン9.2.0.4.0)で記述された単純な関数があります。興味のある方のために、ここにコードがあります:

create or replace
FUNCTION IIF  
   (testExpression NUMBER,
    trueResult NUMBER,
    falseResult NUMBER)
RETURN NUMBER   
AS
BEGIN
   /*
      A simple in-line IF function for use with SQL queries. If the test
      expression evaluates to any non-zero value, it is considered to be 
      true, and the trueResult is returned. Otherwise, falseResult is
      returned.
   */   
   IF (testExpression is null) or (testExpression = 0) THEN
      return falseResult;
   ELSE
      return trueResult;
   END IF;
END IIF;

これはロケット科学ではありません。さて、ここに大きな謎があります。次のSQLステートメントを実行すると、すべてが正常に機能し、期待どおりに機能します。

SELECT IIF(1, 'true', 'false') FROM DUAL;
SELECT IIF(0, 'false', 'true') FROM DUAL;

ただし、以下はOracleから非常に奇妙なエラーを生成します。

SELECT IIF((0 = 1), 'false', 'true') FROM DUAL;

そのエラーは次のとおりです。

ORA-00907: missing right parenthesis.

明らかに、そうではありません。誰かがこのちょっとした奇妙さの説明をたまたま持っているだろうか?

現時点では、Oracleサーバーを窓の外に投げ出さないようにするために、かなりの自制心が必要です。オラクルは、この種の無気力に満ちているようです。

編集:selectステートメントで等式演算子を使用するために使用しなければならないある種の魔法の構文はありますか?

4

5 に答える 5

6

たぶん、あなたがやろうとしていることを説明できるでしょう。CASEまたは関数を探していると思いますが、DECODEよくわかりません。何らかの理由で SQL 言語の粒度に逆らっているようです。

このエラーは、Oracle がselectクエリの句に関係演算子を想定していないために発生します。

SQL> SELECT IIF(1>7, 0, 1) FROM DUAL;
SELECT IIF(1>7, 0, 1) FROM DUAL
            *
ERROR at line 1:
ORA-00907: missing right parenthesis

SQL> SELECT 1=0 FROM DUAL;
SELECT 1=0 FROM DUAL
        *
ERROR at line 1:
ORA-00923: FROM keyword not found where expected

この Ask Tom の記事を参照してください。

于 2009-01-15T23:13:35.997 に答える
3

あなたがしたい

SELECT CASE WHEN *expr* then 'true' else 'false' end col_alias FROM DUAL;

または単純な同等性テストの場合

SELECT DECODE(*val1*,*val2*,'true','false') col_alias FROM dual;

これは、PL/SQL 関数にドロップアウトするよりもはるかに優れたパフォーマンスを発揮します。あなたのアプローチがうまくいかない理由はいくつかあります。

  1. ブール値は Oracle データ型ではありません。

  2. これらはPL/SQLデータ型ですが、それでも数値への暗黙的な変換はありません(ゼロ偽、ゼロ以外の真)

  3. 「式」データ型がないため、SQL エンジンは式を PL/SQL に渡すことができません。

  4. 式を文字列としてPL/SQLに渡しても、PL/SQLエンジンは文字列内の式を動的に評価できません。文字列を動的 SQL ステートメントに組み込み、それを動的に実行して、(文字列や数値などの有効な SQL データ型で) 結果を返す必要があります。

于 2009-01-16T02:15:32.337 に答える
1
  1. Oracle データベースには BOOLEAN 型がないため、「(1=0)」のような式は使用できません。
  2. BOOLEAN 型があったとしても、最初の引数を NUMBER 型として宣言しています。数値、または暗黙的に数値に変換できるものを渡す必要があります。
  3. 最後に、2 番目と 3 番目の引数も数値に変換できないため、「無効な数値」以外に実際にどのような例が生成されたのかわかりません。
于 2009-01-15T23:56:38.763 に答える
0

オラクルを扱ったことがないので、適切なアドバイスを直接提供することはできませんが、ステートメントを見ると、オラクルがブール値から数値を推測する際に問題を抱えている可能性がありますか?..

IIF 署名は最初の引数として NUMBER を想定しており、呼び出しで BOOL 評価を渡しています。

これは単なる考えです。

于 2009-01-15T22:59:59.050 に答える
0

デコードとケースの他に、nvl もあります。

于 2009-01-16T16:14:11.797 に答える