一、regexp在Oracle中的应用
1. 概述
分类:与下列相似,但功能更加强大(‘支持正则表达式’)
(1) regexp_substr : 同 substr 功能相似(‘截取’ 字符串)
(2) regexp_replace: 同 replace 功能相似( ‘替换’ 字符串)
(3) regexp_like : 同 like 功能相似(模糊 ‘匹配’)
(4) regexp_instr : 同 instr 功能相似(返回字符所在 ‘下标’)
– 上述 四个 函数,正则用法相似,知晓一个,其它皆可参考
2 正则匹配规则
| 分组 | 元字符 | 描述 | ||||
|---|---|---|---|---|---|---|
|
|
|
| ||||
|
|
| |||||
|
|
| |||||
|
|
|
| ||||
|
|
| |||||
|
|
|
| ||||
|
|
| |||||
|
|
|
| ||||
|
|
| |||||
|
|
| |||||
|
|
| |||||
|
|
| |||||
|
|
| |||||
| 分组 | 元字符 | 描述 | ||||
|---|---|---|---|---|---|---|
|
|
|
| ||||
|
|
| |||||
|
|
| |||||
|
|
| |||||
|
|
| |||||
|
|
| |||||
|
|
| |||||
|
|
| |||||
3 正则函数
3.1 REGEXP_SUBSTR(String, pattern, [position],[occurrence],[modifier],[subexpression])
3.1.1 参数解释
String: 需要进行正则处理的字符串。
pattern:正则表达式。
position:起始位置(从字符串的第几个开始正则,默认为1,注:数据库中的字符串起始位置为1)。
occurrence:获取第几组通过正则表达式分割出来的组。
modifier:模式(‘i’不区分大小写,‘c’区分大小写。其中默认没‘c’)。
subexpression: 含有子表达式 0-9, 默认 0:不含子表达式,1:第一个子表达式,以此类推
3.1.2 实际用例
eg1:参数subexpression 测试使用
select regexp_substr('abc,CBA121ABC,cba', ',[^,]+,') rs1 -- ,CBA121ABC,
,regexp_substr('1234567890', '(123)(4(56)(78))', 1, 1, 'i', 0) rs2 -- 12345678 不含子表达式
,regexp_substr('1234567890', '(123)(4(56)(78))', 1, 1, 'i', 1) rs3 -- 123 第一个子表达式
,regexp_substr('1234567890', '(123)(4(56)(78))', 1, 1, 'i', 2) rs4 -- 45678 第二个子表达式
,regexp_substr('1234567890', '(123)(4(56)(78))', 1, 1, 'i', 3) rs5 -- 56 依次类推
,regexp_substr('1234567890', '(123)(4(56)(78))', 1, 1, 'i', 4) rs6 -- 78
,regexp_substr('1234567890', '(123)(4(56)(78))', 1, 1, 'i', 5) rs7 --
from dual;
eg2:按照不同的正则使用
with temp_email as (
select 1 user_no, 'a1@qq.com' email from dual union all
select 2 user_no, 'bb2@sina.com' email from dual union all
select 3 user_no, 'ccc3@aliyun.com' email from dual
)
select t.user_no 用户编号
,regexp_substr(t.email,'[[:alnum:]]+') 用户名
,regexp_substr(t.email, '\@[[:alnum:]]+\.[[:alnum:]]+') 邮箱后缀
-- 两者等同
,regexp_substr(t.email,'[a-zA-Z0-9]+') 用户名2
,regexp_substr(t.email, '\@[a-zA-Z0-9]+\.[a-zA-Z0-9]+') 邮箱后缀2
from temp_email t;
–执行结果
用户编号 用户名 邮箱后缀 用户名2 邮箱后缀2
1 1 a1 @qq.com a1 @qq.com
2 2 bb2 @sina.com bb2 @sina.com
3 3 ccc3 @aliyun.com ccc3 @aliyun.com
eg3:配合CONNECT BY使用----小数据量
SELECT REGEXP_SUBSTR('四,五,六,七', '[^,]+', 1, LEVEL, 'i') AS STR
FROM DUAL
CONNECT BY LEVEL <= LENGTH('四,五,六,七') - LENGTH(REPLACE('四,五,六,七', ',', '')) + 1
--connect by level <= REGEXP_COUNT('四,五,六,七','[^,]+')
eg4:配合CONNECT BY使用----大数据量优化版
如果数据量小的话,这样来操作是没问题的,一旦数据量上来了,并且再加上多表联查,查询的速度就会非常慢(非常非常慢!),所以就有了下面的内容,优化.
WITH NEWS_TYPE AS
(SELECT '1' AS Id, 'A,B,C,D' AS Attach_Id
FROM DUAL
UNION ALL
SELECT '2', 'E,F,G,D'
FROM DUAL
UNION ALL
SELECT '3', 'H,R,K,T'
FROM DUAL)
SELECT ID, REGEXP_SUBSTR(ATTACH_ID, '[^,]+', 1, l) AS FILE_ONE
FROM NEWS_TYPE,
(SELECT LEVEL l
FROM DUAL
CONNECT BY LEVEL <= 100 --此处的100,可以通过取 REGEXP_COUNT(NEWS_TYPE.ATTACH_ID,'[^,]+')的最大值来代替
) b
WHERE l <= REGEXP_COUNT(NEWS_TYPE.ATTACH_ID, '[^,]+')
AND regexp_like(id, '^[0-9]+');
–执行结果
STR
1 四
2 五
3 六
4 七
3.2 regexp_replace(Srcstr, pattern, [replacestr],[position],[occurrence],[modifier])
3.2.1 参数解释
Srcstr:需要进行正则处理的字符串。
pattern:正则表达式。
replacestr:需要替换成什么字段
position:起始位置(从字符串的第几个开始正则,默认为1,注:数据库中的字符串起始位置为1)。
occurrence:bigint类型常量,必须大于等于0,
大于0:表示将第几次匹配替换成replace_string,
等于0:表示替换掉所有的匹配子串。
其它类型或小于0抛异常。
modifier:模式(‘i’不区分大小写,‘c’区分大小写。其中默认没‘c’)。
3.2.2 实际用例
eg1:按照规则替换字符
with temp_strings as (
select 'abc123' str from dual union all
select '123abc' str from dual union all
select 'adf13994893964adf13453983743 ' str from dual union all
select '2020年09月17日' str from dual union all
select 'a1b2c3' str from dual
)
select t.str 源字符串,
regexp_replace(t.str, '[0-9]', '', 1) as 无数字字符串,
regexp_replace(str, '.*(1[[:digit:]]{10}).*','\1') as 截取手机号,
REGEXP_REPLACE(T2.PAY_END_DT, '[^0-9]') as 截取所有的数字
from temp_strings t;
执行结果
源字符串 无数字字符串
1 abc123 abc
2 123abc abc
3 a1b2c3 abc
eg2: regexp_replace和listagg组合使用,实现对分组聚合后的结果进行去重
eg2.1 :数字汇总去重
WITH NEWS_TYPE_VARCHAR AS
(SELECT 't1' AS ID, 'A' AS Attach_Id
FROM DUAL
UNION ALL
SELECT 't1', 'A'
FROM DUAL
UNION ALL
SELECT 't1', 'C'
FROM DUAL
UNION ALL
SELECT 't2', 'A'
FROM DUAL
UNION ALL
SELECT 't2', 'B'
FROM DUAL),
NEWS_TYPE_NUMBER AS
(SELECT 't1' AS ID, '11' AS Attach_Id
FROM DUAL
UNION ALL
SELECT 't1', '12'
FROM DUAL
UNION ALL
SELECT 't1', '12'
FROM DUAL
UNION ALL
SELECT 't2', '1'
FROM DUAL
UNION ALL
SELECT 't2', '1'
FROM DUAL)
select 'VARCHAR' AS QULB,
T.ID,
listagg(T.Attach_Id, ',') within group(order by 1),
regexp_replace((listagg(T.Attach_Id, ',') within group(order by 1)),
'(,[[:digit:]]+)(\1)+',
'\1') GROUP_CODE
from NEWS_TYPE_VARCHAR t
GROUP BY T.ID
UNION ALL
select 'NUMBER',
T.ID,
listagg(T.Attach_Id, ',') within group(order by 1),
regexp_replace((listagg(T.Attach_Id, ',') within group(order by 1)),
'(,[[:digit:]]+)(\1)+',
'\1') GROUP_CODE
from NEWS_TYPE_NUMBER t
GROUP BY T.ID;
–执行结果:只对数字生效,字符串无效
1 VARCHAR t1 A,A,C A,A,C
2 VARCHAR t2 A,B A,B
3 NUMBER t1 11,12,12 11,12
4 NUMBER t2 1,1 1,1
eg2.2:对任何以逗号隔开的任何字符串(包括数字)去重
//注意:这只能对相邻的字符串去重,因此要对字符串去重,必须先通过order by排序后去重
WITH NEWS_TYPE_VARCHAR AS
(SELECT 't1' AS ID, 'A' AS Attach_Id
FROM DUAL
UNION ALL
SELECT 't1', 'A'
FROM DUAL
UNION ALL
SELECT 't1', 'C'
FROM DUAL
UNION ALL
SELECT 't2', 'A'
FROM DUAL
UNION ALL
SELECT 't2', 'B'
FROM DUAL),
NEWS_TYPE_NUMBER AS
(SELECT 't1' AS ID, '11' AS Attach_Id
FROM DUAL
UNION ALL
SELECT 't1', '12'
FROM DUAL
UNION ALL
SELECT 't1', '12'
FROM DUAL
UNION ALL
SELECT 't2', '1'
FROM DUAL
UNION ALL
SELECT 't2', '1'
FROM DUAL)
select 'VARCHAR' AS QULB,
T.ID,
listagg(T.Attach_Id, ',') within group(order by 1),
regexp_replace((listagg(T.Attach_Id, ',') within group(order by 1)),
'([^,]+)(,\1)*(,|$)',
'\1\3') GROUP_CODE
from NEWS_TYPE_VARCHAR t
GROUP BY T.ID
UNION ALL
select 'NUMBER',
T.ID,
listagg(T.Attach_Id, ',') within group(order by 1),
regexp_replace((listagg(T.Attach_Id, ',') within group(order by 1)),
'([^,]+)(,\1)*(,|$)',
'\1\3') GROUP_CODE
from NEWS_TYPE_NUMBER t
GROUP BY T.ID;
–执行结果
1 VARCHAR t1 A,A,C A,C
2 VARCHAR t2 A,B A,B
3 NUMBER t1 11,12,12 11,12
4 NUMBER t2 1,1 1
eg2.3:以+号分割
WITH NEWS_TYPE_VARCHAR AS
(SELECT 't1' AS ID, 'A' AS Attach_Id
FROM DUAL
UNION ALL
SELECT 't1', 'A'
FROM DUAL
UNION ALL
SELECT 't1', 'C'
FROM DUAL
UNION ALL
SELECT 't2', 'A'
FROM DUAL
UNION ALL
SELECT 't2', 'B'
FROM DUAL)
select 'VARCHAR' AS QULB,
T.ID,
listagg(T.Attach_Id, '+') within group(order by 1),
regexp_replace((listagg(T.Attach_Id, '+') within group(order by 1)),
'([^\+]+)(\+\1)*(\+|$)'
,'\1\3') GROUP_CODE
--,to_char(rtrim(xmlagg(xmlparse(content upper(Attach_Id) || '+' wellformed) order by 1).getclobval() ,'+')) item_name 未能实现去重
from NEWS_TYPE_VARCHAR t
GROUP BY T.ID;
–执行结果:
1 VARCHAR t1 A+A+C A+C
2 VARCHAR t2 A+B A+B
eg2.4 特殊情况,未实操演示
//如果遇到字符串过长,则可以使用如下语句
regexp_replace(rtrim(xmlagg(xmlparse(content upper(product_id) || ',' wellformed) order by product_id).getclobval() ,','),'([^,]+)(,\1)*(,|$)', '\1\3') product_id,
//如果是mybatis中使用如下语句,否则会报错
regexp_replace((listagg(product_id, ',') within group(order by product_id)), '([^,]+)(,\1)*(,|$)','\1\3') product_id
eg3:取正则的不同部分处理
SELECT regexp_replace('+86 13811112222',
'(\+[0-9]{2})( )([0-9]{3})([0-9]{4})([0-9]{4})',
'(\1)\3-\4-\5'), --格式化手机号 ’+‘在正则表达式中有定义,需要转义。\1表示引用的第一个组 (+86)138-1111-2222
regexp_replace('123.456.7890',
'([[:digit:]]{3})\.([[:digit:]]{3})\.([[:digit:]]{4})',
'(\1)\2-\3'), --(123)456-7890
regexp_replace('123.456.7890',
'([0-9]{3})\.([0-9]{3})\.([0-9]{4})',
'(\1)\2-\3'), --(123)456-7890
regexp_replace('abcdefg123456ABC', '(.)', '\1 ',1), --a b c d e f g 1 2 3 4 5 6 A B C
regexp_replace('abcdefg123456ABC', '(.)', '\1 ',2) --ab c d e f g 1 2 3 4 5 6 A B C
regexp_replace('abcd','(.*)(.)$','\1',1) --abc
regexp_replace('abcd','(.*)(.)$','\1-\2',1) --abc-d
from dual;
eg4: 其他案例:
SELECT regexp_replace('abcd','(.)','\2',1) --结果为'',因为pattern中只定义了一个组,引用的第二个组不存在。
,regexp_replace('abcd','(.*)(.)$','\2',1) --结果为'd'
,regexp_replace('abcd','(.*)(.)$','\1',1) --结果为'abc'
,regexp_replace('abcd','(.*)(.)$','\1-\2',1) --结果为'abc-d'
,regexp_replace('abcd','a','\1',1) --,结果为” \1bcd”,因为在pattern中没有组的定义,所以\1直接输出为字符。
from dual;
3.3 regexp_like(Srcstr, pattern, [replacestr],[position],[occurrence],[modifier])
3.3.1 参数解释
Srcstr:需要进行正则处理的字符串。
pattern:正则表达式。
replacestr:需要替换成什么字段
position:起始位置(从字符串的第几个开始正则,默认为1,注:数据库中的字符串起始位置为1)。
occurrence:bigint类型常量,必须大于等于0,
大于0:表示将第几次匹配替换成replace_string,
等于0:表示替换掉所有的匹配子串。
其它类型或小于0抛异常。
modifier:模式(‘i’不区分大小写,‘c’区分大小写。其中默认没‘c’)。
3.3.2 实际用例
with regexp_like_temp_table as (
select 'adf13994893964ad f13453983743' str from dual
union all
select '1222260' str from dual
union all
select '122a260' str from dual
union all
select '1badfadfa' str from dual
union all
select '1Badfadfa' str from dual
union all
select 'adfsdfsfadf adadf' str from dual
union all
select 'adfsdfsfC,adfadadf' str from dual
)
select *
from regexp_like_temp_table
where regexp_like(str, '.*(1[[:digit:]]{10}).*') --查询包含以1开头的11位数据
or (regexp_like(str, '1....60')
or str like '1____60' ) --"____"表示4个"_" 以 1 开头 60 结尾的记录并且长度是 7 位
or (regexp_like(str, '^1[0-9]{4}60$')
or regexp_like(str, '^1[[:digit:]]{4}60$')) --以 1 开头 60 结尾的记录并且长度是 7 位且全部是数字的记录
or regexp_like(str, '^[^[:digit:]]+$') --[] 内的 ^ 表示 '非' 查询 str 中不包含任何数字的记录
or not regexp_like(str, '^[[:digit:]]+$') --查询 str 中不是纯数字的记录
or (regexp_like(str, '^(12)|^(1b)')
or regexp_like(str, '^1[2b]')) --查询以 12 或 1b 开头的记录,区分大小写
or regexp_like(str, '^1[2b]', 'i') --以 12 或 1b 开头的记录,不区分大小写
OR regexp_like(str, '^([a-z]+|[0-9]+)$') --查询所有均为 小写字母 或 数字的记录
OR regexp_like(str, '[[:space:]]') --查询包含 空白 的记录
OR regexp_like(str, '[[:punct:]]') --查询包含 标点符号 的记录
OR REGEXP_LIKE(lkm_mobile,'[1][1234567890]{10}') --手机号必须是11位数字,开头是1
OR REGEXP_LIKE(lkm_tel,'[0][1234567890]2,3[0][1234567890]2,3-[1234567890]{7,8}') --电话号码必须是(010)-1234567,区号3,4位,座机号7,8位
OR REGEXP_LIKE(test,'[0][0123456789]2,3[0][0123456789]2,3-[0123456789]{7,8}') --验证必须是电话号码:例:(010)-6666666
;
3.4 regexp_instr(String, pattern, [position],[occurrence],[retrurnparam],[modifier],[subexpression])
3.4.1 参数解释
srcstr : 源字符串 – source string
pattern : 正则表达式
position : 起始位置,默认 1
occurrence : 第几次出现,默认 1(匹配成功的次数,依次递增)
returnparam : 返回参数对应的下标(0:第一个位置的下标,非0:最后一个位置的下标)
modifier : 模式(‘i’: 不区分大小写,‘c’: 区分大小写。 默认 ‘c’)
subexpression: 含有子表达式 0-9, 默认 0:不含子表达式,1:第一个子表达式,以此类推
3.4.2 实际用例
select regexp_instr('1,23,456,7890', '[0-9]+', 1, 3) --匹配到的第一个字符下标, --查询结果: 6
,regexp_instr('1,23,456,7890', '[0-9]+', 1, 3, 1) --最后一个字符后一位的下标, --查询结果: 9
,regexp_instr('1234567890', '(123)(4)(56)(78)', 1, 1, 0, 'i', 4) --匹配到的第四个子表达式 --查询结果: 7
from dual;
二、DBMS_RANDOM随机函数应用
1.DBMS_RANDOM.STRING (opt IN CHAR,len IN NUMBER) RETURN VARCHAR2;
1.1 参数解释
参数len指定生成的字符串的长度。
参数opt指定生成的字符串的样式,允许的取值及其表示的含义
1.2 参数用例含义
| 取值 | 含义 | ||||
|---|---|---|---|---|---|
|
|
| ||||
|
|
| ||||
|
|
| ||||
|
|
| ||||
|
|
|
1.3 执行示例
select
DBMS_RANDOM.STRING ('u',6) --JETRGA
,DBMS_RANDOM.STRING ('l',6) --akntyk
,DBMS_RANDOM.STRING ('a',6) --iWWCkT
,DBMS_RANDOM.STRING ('x',6) --0D4N24
,DBMS_RANDOM.STRING ('p',6) --TUB=rF
,DBMS_RANDOM.STRING ('U',6) --LNDYKS
,DBMS_RANDOM.STRING ('L',6) --mlajxi
,DBMS_RANDOM.STRING ('A',6) --MqgIaR
,DBMS_RANDOM.STRING ('X',6) --H53KN4
,DBMS_RANDOM.STRING ('P',6) --M3[.ig
from dual;
三、窗口分析函数的应用:FIRST_VALUE\LAST_VALUE\lag\lead
1 概述
1.1 说明
(1) 均属于 ‘分析函数’: 每行一条记录(不聚合)
(2) + over(partition by 列1 order by 列2) – 一同使用
1.2 含义
first_value() – 第一个
last_value() – 最后一个 特别注意:是 ‘第一个’ 到 ‘当前记录’ 排行中的 ‘最后一个’ rows between unbounded preceding and current row
lag() – 上一个
lead() – 下一个
2 应用实例
2.1 first_value()和last_value()的使用
with student_info as (
select 1 sno, 'a' sname, 18 age, date '2020-01-01' create_date from dual union all
select 2 sno, 'b' sname, 18 age, date '2020-02-01' create_date from dual union all
select 3 sno, 'c' sname, 18 age, date '2020-03-01' create_date from dual
)
select si.sno,
si.sname,
si.age,
si.create_date,
first_value(si.sname) over(partition by si.age order by si.create_date) 第一条记录,
last_value(si.sname) over(partition by si.age order by si.create_date) 至当前最后一条记录,
first_value(si.sname) over(partition by si.age order by si.create_date desc) 所有记录中最后一条
from student_info si;
–执行结果
sno sname age create_date 第一条记录 至当前最后一条记录 所有记录中最后一条
1 a 18 2020/1/1 a a c
2 b 18 2020/2/1 a b c
3 c 18 2020/3/1 a c c
2.2 lag() + lead()
with student_info as (
select 1 sno, 'a' sname, 18 age, date '2020-01-01' create_date from dual union all
select 2 sno, 'b' sname, 18 age, date '2020-02-01' create_date from dual union all
select 3 sno, 'c' sname, 18 age, date '2020-03-01' create_date from dual
)
select si.sno,
si.sname,
si.age,
si.create_date,
lag(si.sname) over(partition by si.age order by si.create_date) 上一条记录,
lead(si.sname) over(partition by si.age order by si.create_date) 下一条记录
from student_info si;
–执行结果
sno sname age create_date 上一条记录 下一条记录
1 a 18 2020/1/1 b
2 b 18 2020/2/1 a c
3 c 18 2020/3/1 b
3 扩展
3.1 保持排序,且避免返回多行 keep()
/*
要点:在子查询中 既能达到排序的目的,又不用担心 '返回多行'
示例:查询各部门第一个入司的人
*/
select d.*,
(select max(e.ename) keep(dense_rank first order by e.hiredate)
-- 报错:子查询返回多行
-- max(e.ename) over(partition by e.deptno order by e.hiredate)
from scott.emp e
where e.deptno = d.deptno) 第一个入司的人
from scott.dept d;
四、Execute immediate语句和using关键字实现动态SQL
1 概述
1.1 Execute immediate 动态SQL语句 into 出参1,出参2… using 形参1,形参2…
insert、update 是提取 操作后 的数据,delete 是提取 操作前 的数据。
1.2 Execute immediate 动态SQL语句 using 形参1,形参2… returning into 出参1,出参2…
returning 子句只能用于insert、update、delete。
returning into 在 动态sql内部和外面都要写,内部变量需要加上标识符“:”,外面不用,且外面的 returning 后面不加字段直接 into。
returning 不支持 record
2 应用实例
准备测试表
create table test1 (id number(2));
create table test2 (id number(2));
--向测试表中添加数据
begin
for i in 1..50 loop
insert into test1 values(round(dbms_random.value()*10));
end loop;
commit;
end;
begin
for i in 1..100 loop
insert into test2 values(round(dbms_random.value()*10));
end loop;
commit;
end;
2.1 into的使用
--目标:根据test1表的ID,查询在test2表出现的次数并输出。
declare
flag number;
begin
--循环获取test1表的数据
--可以在SQL后面用||拼接形参,也可以使用 :参数名 作为占位符
for test1 in (select distinct id from test1 order by id) loop
execute immediate 'select count(1) from test2 where id = :1'
into flag
--注意占位符和using后的参数绑定是按照前后顺序的
using test1.id;
dbms_output.put_line('ID为'||test1.id||'的数量为:'||flag);
end loop;
end;
–执行结果
ID为0的数量为:5
ID为1的数量为:10
ID为2的数量为:11
ID为3的数量为:15
ID为4的数量为:12
ID为5的数量为:7
ID为6的数量为:8
ID为7的数量为:15
ID为8的数量为:9
ID为9的数量为:10
ID为10的数量为:5
2.2 returning的使用
--目标:根据传入的ID删除test2表的数并输出删除条数。
declare
type v_table_id is table of test1.id%type;
v_id v_table_id;
flag number := 1;
begin
execute immediate 'delete test1 where id =' || flag ||
'returning id into :v_id'
returning bulk collect into v_id; --v_id 是一个list集合
rollback;
dbms_output.put_line('总删除数:'||v_id.count);
for i in 1..v_id.count loop
dbms_output.put_line('删除值'||i||':'||v_id(i));
end loop;
end;
–执行结果
总删除数:6
删除值1:1
删除值2:1
删除值3:1
删除值4:1
删除值5:1
删除值6:1
五、约束的应用:FIRST_VALUE\LAST_VALUE\lag\lead
1 概述 Oracle数据库中的约束有五种约束,分别是:
1.1 实体完整性:主键约束、唯一性约束(可以为空)
Constraint Primary Key|Unique (<column_name>)
1.2 域完整性:check约束
Constraint Check (列条件表达式)
1.3 引用完整性:Foreign KEY约束
Constraint Foreign key (<column_name>) references <table_name>(<column_name>)
1.4 默认约束(默认值)
column_name column_type default ‘默认值’ --创建表或修改表字段
2 约束增删改查
2.1 删除约束
alter table 表名 drop constraint 约束名称;
2.2 禁用/启用约束
alter table 表名 disable/enable constraint 约束名称;
2.3 修改约束名称
alter table 表名 rename constraint 旧约束名称 to 新约束名称;
2.4 添加约束
alter table test add constraint test_pk primary key(id); --添加主键约束(非空,不重复)(给test表的id这一列添加主键约束)
alter table test add constraint test_unique_name unique(name); --添加唯一性约束(不重复,可以为空)(给test表name这一列添加唯一性约束)
alter table test add constraint test_cus_no_fk_1 foreign key(cus_no) references cus_info (cus_no)--添加外键约束(保证外键的值取关联表里关联字段的值)(给表test的列cus_no设为外键,关联表cus_info的列cus_no
alter table test add constraint test_name_check check(name in ('a','b','c') ) /* check(REGEXP_LIKE(lkm_mobile,'[1][1234567890]{10}')) */; --完整性约束(代表一个字段或者多个字段的取值是有限定范围的)
create table t1 (tname varchar2(20) default 'yang');--默认约束-创建表
alter table test_table add (TEST_D VARCHAR2(100) NOT NULL default 'yang' );--默认约束-修改列属性
2118

被折叠的 条评论
为什么被折叠?



