13

次のようなテーブルがあるとします。

CREATE TABLE "MyTable" 
(
  "MyColumn" NUMBER NOT NULL
);

次のようなビューを作成したい:

CREATE VIEW "MyView" AS
SELECT
    CAST("MyColumn" AS BINARY_DOUBLE) AS "MyColumn"
FROM "MyTable";

列「MyColumn」が「NOT NULL」の場合のみ。

SQL Server では、これは非常に簡単です。

CREATE VIEW [MyView] AS
SELECT
    ISNULL(CAST([MyColumn] AS Float), 0.0) AS [MyColumn]
FROM [MyTable];

ただし、Oracle の同等の結果は「NULL」列になります。

CREATE VIEW "MyView" AS
SELECT
    NVL(CAST("MyColumn" AS BINARY_DOUBLE), 0.0) AS "MyColumn"
FROM "MyTable";

メタデータでビューの列を「NOT NULL」としてマークするようにOracleに強制する方法はありますか?

4

2 に答える 2

8

ビューに not null または check 制約を追加することはできません。これと同じページの「NOT NULL 制約の制限」および「チェック制約の制限」を参照してください。ビューに (冗長な where 句に対して) を追加することはできますが、それはデータ ディクショナリのwith check optionようにマークされません。not null

この効果を得るために私が考えることができる唯一の方法は、11g を使用している場合、キャスト値をテーブルの仮想列として追加し、(まだ必要な場合) それに対するビューを作成することです。

ALTER TABLE "MyTable" ADD "MyBDColumn" AS
    (CAST("MyColumn" AS BINARY_DOUBLE)) NOT NULL;

CREATE OR REPLACE VIEW "MyView" AS
SELECT
    "MyBDColumn" AS "MyColumn"
FROM "MyTable";

desc "MyView"

 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 MyColumn                                  NOT NULL BINARY_DOUBLE

dba.se のコメントで、これは何かをモックアップするためのものだと言ったので、通常の列とトリガーを使用して仮想列をシミュレートできます。

CREATE TABLE "MyTable" 
(
  "MyColumn" NUMBER NOT NULL,
  "MyBDColumn" BINARY_DOUBLE NOT NULL
);

CREATE TRIGGER "MyTrigger" before update or insert on "MyTable"
FOR EACH ROW
BEGIN
    :new."MyBDColumn" := :new."MyColumn";
END;
/

CREATE VIEW "MyView" AS
SELECT
    "MyBDColumn" AS "MyColumn"
FROM "MyTable";

INSERT INTO "MyTable" ("MyColumn") values (2);

SELECT * FROM "MyView";

  MyColumn
----------
  2.0E+000

そしてdesc "MyView"まだ与えます:

 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 MyColumn                                  NOT NULL BINARY_DOUBLE

Leigh が述べたように (dba.se でも)、ビューを挿入/更新したい場合はinstead of、VC または偽のバージョンでトリガーを使用できます。

于 2012-06-19T10:03:06.910 に答える
1

ビュー列に NOT NULL 制約を設定できる場合、問題の列が NULL の場合、ビューからの SELECT は失敗すると思います。これが意図である場合、以下はあなたが探しているものを与えるかもしれません:

CREATE OR REPLACE VIEW some_view AS
  SELECT some_field,
         some_other_field,
         CASE
           WHEN field_of_interest IS NOT NULL
             THEN CAST(field_of_interest AS BINARY_DOUBLE)
             ELSE 1 / 0
         END AS field_of_interest_not_null
     FROM some_table;

あまり魅力的ではなく、CASE の ELSE 分岐が実行されると、"ORA-01476: 除算がゼロに等しい" という醜いメッセージが表示されますが、これはおそらく "より良い" 方向への一歩です。

共有してお楽しみください。


編集:目的が、ターゲット列が null ではない行のみを選択することである場合、次のように、ビューに WHERE 句を追加できます。

CREATE OR REPLACE VIEW some_view AS
  SELECT some_field,
         some_other_field,
         CAST(field_of_interest AS BINARY_DOUBLE) AS field_of_interest
    FROM some_table
    WHERE field_of_interest IS NOT NULL;

YMMV。


EDIT2: SQL Server の例を見ると、列が NULL にならないようにするために ISNULL 関数が使用されているようです。これが許容できる場合は、次のことができます。

CREATE OR REPLACE VIEW some_view AS
  SELECT some_field,
         some_other_field,
         CAST(NVL(field_of_interest, 0.0) AS BINARY_DOUBLE) AS field_of_interest
    FROM some_table
    WHERE field_of_interest IS NOT NULL;

Bullwinkle の言葉を引用すると、「今回は間違いなく!!!」:-)

于 2012-06-19T10:58:24.833 に答える