5

Oracle SQL開発者でこのようなことをすることは可能ですか?

CREATE FUNCTION fnCheckValid(accountidd IN NUMBER) 
RETURN NUMBER 
   IS retval NUMBER(4,0);
   BEGIN 
      SELECT COUNT(accountid_fk) 
      INTO retval 
      FROM tbl_AccountAuthentications 
      WHERE accountid_fk = accountidd; 
      RETURN(retval); 
    END;
/


ALTER TABLE tbl_AccountAuthentications
ADD CONSTRAINT chkCheckvalid CHECK(fnCheckValid(accountid_fk) <= 1);

私が取得し続けるエラーは

Error starting at line 999 in command:
ALTER TABLE tbl_AccountAuthentications
ADD CONSTRAINT chkCheckvalid CHECK(fnCheckValid(accountid_fk) <= 1)
Error report:
SQL Error: ORA-00904: "FNCHECKVALID": invalid identifier
00904. 00000 -  "%s: invalid identifier"
*Cause:    
*Action:

関数は作成されており、見つけることができますが、それを呼び出そうとすると、そのエラーが発生し続けます

これは私が達成しようとしているものです

AccountID    RegularID     OpenID
 1            5             null
 1            null          10
 1            null          11
 1            6                             <-- Forbidden

ユーザーは 2 つの通常のアカウントを作成することはできませんが、必要な数の OpenID アカウントを作成できます。

テーブルは次のように設定されています

CREATE TABLE tbl_AccountAuthentications(
        newAuthID NUMBER(4,0)
          CONSTRAINT naid_pk PRIMARY KEY,        
        accountid_fk NUMBER(4,0)
          CONSTRAINT accid_fk 
            REFERENCES tbl_UserAccounts(account_id),
        regularid_fk NUMBER(4,0)
          CONSTRAINT rgid_fk
            REFERENCES tbl_StrongRoom(password_id),
        openid_fk NUMBER(4,0)
          CONSTRAINT opid_fk
            REFERENCES tbl_OpenID(openid)
);
4

2 に答える 2

10

いいえ、それはできません。チェック制約の制限を参照してください。

  • ユーザー定義関数の呼び出し

ただし、仮想列を使用して回避策を作成できます

ALTER TABLE tbl_AccountAuthentications ADD (fnCheck NUMBER GENERATED ALWAYS AS (fnCheckValid(accountid_fk)) VIRTUAL);


ALTER TABLE tbl_AccountAuthentications
ADD CONSTRAINT chkCheckvalid CHECK(fnCheck <= 1);

関数は DETERMINISTIC でなければならないことに注意してください。それ以外の場合は機能しません。Oracle は、関数が実際に決定論的であるかどうかを検証しません。キーワードをチェックするだけです。これは許可されています (まったく意味がありませんが):

CREATE OR REPLACE FUNCTION DET_FUNCTION RETURN NUMBER DETERMINISTIC IS 
BEGIN 
    RETURN DBMS_RANDOM.RANDOM();
END;
/
于 2017-01-04T15:23:29.380 に答える