在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) );
您要确保 AccountID 和 RegularID 列一起唯一,无论 OpenID 有多少个值。
正如您已经确定的那样,执行此操作的唯一方法是对其进行 约束 。您会在注释中注意到您已尝试使用触发器。这并 没有 在数据库中限制值,它只是确保它试图启用触发器时进行验证。我希望当您尝试它时,收到错误消息 “ ORA-04091:正在变异,触发器/功能可能看不到它”。 从表中选择时,您正在更改(插入或更新)过程中。
如果您必须对此加以限制,那就是您应该做的。这样做的问题是您的表未规范化。因此,将其标准化。使用两个表,而不要使用一个表。
首先,您需要您的 RegularID 在 AccountID 上是唯一的,这意味着它应该在此级别存储。tbl_UserAccounts在此标识符上似乎是唯一的,因此请更改此表并在其中存储您的 RegularID 。
tbl_UserAccounts
接下来,您需要一个表,该表具有与用户可能想要的一样多的 OpenID 。这意味着您需要一个在 AccountID 和 OpenID 1上唯一的表。
create table openid_account_auth ( , account_id number(4,0) , open_id number(4,0) , constraint pk_openid_account_auth primary key (account_id, open_id) , constraint fk_openid_account_auth_accid foreign key (account_id) references tbl_UserAccounts(account_id) , constraint fk_openid_account_auth_open foreign key (open_id) references tbl_OpenID (openid) );
此表(以及您自己的表)上的一点表示,多个帐户可以具有相同的 OpenID 。如果您不打算这样做,则应在其中添加 AccountID 作为外键tbl_OpenID,这是确保每个 OpenID 仅与一个 AccountID 关联的唯一方法。
tbl_OpenID
如果确实需要使用该视图,则可以创建视图以相同的方式获取信息。我不确定你为什么会这么做。
create or replace view AccountAuthentications as select account_id, regular_id, null from user_accounts union all select account_id, null, open_id from openid_account_auth;
简而言之,除非受到严格的约束,否则您应该始终在自然级别存储数据,并使用数据库来确保保持完整性。如果随后需要稍微不同地使用数据,则可以使用视图或实例化视图等。
1.很抱歉,但是我不能让自己在每个表的名称前加上tbl_。
tbl_