thi*_*ode 5 sql oracle oracle11g
我们正在测试Oracle的工作,并负责在Oracle上构建所有数据库对象(表,过程,触发器等),我们目前使用的是Microsoft SQL Server 2008 R2.我们几乎为所有ID列使用uniqueidentifier.我用这个函数来创建GUID:
CREATE OR REPLACE FUNCTION NEWID RETURN CHAR IS guid CHAR(36) ;
BEGIN
SELECT SYS_GUID() INTO guid FROM DUAL;
guid :=
SUBSTR(guid, 1, 8) ||
'-' || SUBSTR(guid, 9, 4) ||
'-' || SUBSTR(guid, 13, 4) ||
'-' || SUBSTR(guid, 17, 4) ||
'-' || SUBSTR(guid, 21);
RETURN guid;
END NEWID;
/
Run Code Online (Sandbox Code Playgroud)
但是现在我无法弄清楚如何在创建表时将它用作列的默认值.这是一个非工作的例子:
CREATE TABLE "NonWorkingExample"
(
"ID" CHAR(36) NOT NULL DEFAULT NEWID(),
"UnitNumber" NUMBER(38) NOT NULL,
"StartDateTime" TIMESTAMP NOT NULL,
"EndDateTime" TIMESTAMP NULL,
CONSTRAINT PK_RentalAgreements PRIMARY KEY ("ID")
);
Run Code Online (Sandbox Code Playgroud)
而错误:
Error starting at line 1 in command:
CREATE TABLE "NonWorkingExample"
(
"ID" CHAR(36) NOT NULL DEFAULT NEWID(),
"UnitNumber" NUMBER(38) NOT NULL,
"StartDateTime" TIMESTAMP NOT NULL,
"EndDateTime" TIMESTAMP NULL,
CONSTRAINT PK_RentalAgreements PRIMARY KEY ("ID")
)
Error at Command Line:3 Column:58
Error report:
SQL Error: ORA-00907: missing right parenthesis
00907. 00000 - "missing right parenthesis"
*Cause:
*Action:
Run Code Online (Sandbox Code Playgroud)
任何帮助将非常感激.谢谢.
Jus*_*ave 11
我完全同意其他答案,如果你真的想调用一个函数,你需要使用一个触发器,或者你需要在函数调用中嵌入函数调用INSERT.在函数调用中嵌入函数调用INSERT比强制Oracle为您插入的每一行执行触发器更有效.
但是,我应该指出,您可以SYS_GUID()单独使用作为列的默认值而无需担心触发器
SQL> create table foo (
2 col1 varchar2(32) default sys_guid(),
3 col2 number
4 );
Table created.
SQL> insert into foo( col2 ) values( 1 );
1 row created.
SQL> select * from foo;
COL1 COL2
-------------------------------- ----------
7B64E8AE7404421C80A590F65873CD79 1
Run Code Online (Sandbox Code Playgroud)
你真的需要GUID值中的额外破折号吗?您是否可以仅在显示数据时添加破折号?或者,因为您使用的是11g,所以添加一个基于函数的虚拟列,可以将您的无破折号GUID转换为您喜欢的格式的GUID?
既然你来自SQL Server,我应该指出,在Oracle中使用序列来填充合成主键而不是使用GUID是常规的.使用序列填充密钥通常比调用SYS_GUID更有效.
正如@Kerri暗示的那样,您不能将PLSQL函数用作表定义中的默认值.Oracle文档中的相关声明是"DEFAULT表达式不能包含对PL/SQL函数的引用......".
除了作为插入格式化GUID的唯一方法之外,触发器还提供了第二个优势:与默认值不同,触发器设置的值不能被粗心的开发人员覆盖.
顺便说一句,你应该真正修改你的newid函数来使用直接赋值而不是select ... from dual:
CREATE OR REPLACE FUNCTION NEWID RETURN CHAR IS
guid VARCHAR(36);
BEGIN
guid := SYS_GUID();
guid :=
SUBSTR(guid, 1, 8) ||
'-' || SUBSTR(guid, 9, 4) ||
'-' || SUBSTR(guid, 13, 4) ||
'-' || SUBSTR(guid, 17, 4) ||
'-' || SUBSTR(guid, 21);
RETURN guid;
END NEWID;
/
Run Code Online (Sandbox Code Playgroud)
最后,我建议你用varchar2而不是char.与流行的 观点相反,没有存储或效率优势char,所以你不妨varchar2用于所有事情,只是为了简单起见.
建议:
例如:
CREATE TRIGGER SetGUIDforTableXYZ BEFORE INSERT ON TableXYZ
FOR EACH ROW
BEGIN
:new.ID := NEWID();
END;
Run Code Online (Sandbox Code Playgroud)
这应该做的伎俩(假设我没有搞砸某处的语法).
您无法使用此功能.您没有看到它,因为您的语法错误(在CONSTRAINTS之前为DEFAULT).你应该有:
"ID" CHAR(36) DEFAULT NEWID() NOT NULL ,
Run Code Online (Sandbox Code Playgroud)
此时您将收到以下消息(11g):
SQL> create table tt (id varchar2(36) default newid() not null);
create table tt (id varchar2(36) default newid() not null)
*
ERROR at line 1:
ORA-04044: procedure, function, package, or type is not allowed here
SQL>
Run Code Online (Sandbox Code Playgroud)
正如@Kerri所说,它会触发自动执行此操作.
| 归档时间: |
|
| 查看次数: |
15662 次 |
| 最近记录: |