SQL 常见操作汇总

SQL 专栏收录该内容
5 篇文章 0 订阅

写在前面

会涉及到以下内容:

改密码,本机SQL developer(windows)连接,删表,Oracle 数据类型介绍,建表,插入(手动+循环)小规模模拟数据,基础简单的SQL。

copy 表 +(循环)插入大规模(百万级)数据,基础简单的 SQL again ,效率对比,数据导出成执行脚本 ,数据导入, 换成服务器-客户端请求形式, 基础简单的SQL again, 效率对比 again ,

1 Oracle用户名即将失效,或者已经失效。

oracle 口令一般默认有效期是180天,过期失效。

我们可以将过期时间设为无限,但出于安全不建议这样做。

我们可以在即将失效,或者已经失效的时候,登录 system 用户,执行更改密码指令,xxx对应用户名,xxxx对应新密码:

#创建用户
create user profile identified by 123;
grant connect,resource,dba to profile;
grant create session, connect, resource to profile;

#改密码
alter user XXX identified by XXXX

2 Oracle SQL developer 登录

前提:安装的时候基本上是默认设置,而且是在本机安装的。

下图展示了一个登录 c##profile 用户需要填写的信息

端口默认是1521,SID默认是 orcl

 

3 删掉一个表

删掉所有数据

truncate table COMMENT_DETAIL;

删掉数据和这个表

drop table COMMENT_DETAIL;
drop table USER_ORDER_HIS;
drop table USER_ORDER;
drop table USER_BASKET;
drop table PRE_ORDER;
drop table DEMO_USER_DETAIL;
drop table DEMO_RESOURCE_DETAIL;
drop table DEMO_RESOURCE;
drop table DEMO_USER;

4 新建一些表

这里我会使用到如下类型:

char ;varchar2 ;number; float; date;

至于blob clob ,我那个 shop 的例子有已经充分展示了 小数据量下 Java + Oracle 应该怎么用,这里就不试了。

oracle 6 大数据类型 (参考 https://blog.csdn.net/wuya814070935/article/details/73163604

字符串类型

  • char : CHAR类型,定长字符串,会用空格填充来达到其最大长度。非NULL的CHAR(12)总是包含12字节信息。CHAR字段最多可以存储2,000字节的信息。如果创建表时,不指定CHAR长度,则默认为1。
  • nchar : 这是一个包含UNICODE格式数据的定长字符串。NCHAR字段最多可以存储2,000字节的信息。它的最大长度取决于国家字符集。
  • varchar2 :变长字符串,与CHAR类型不同,它不会使用空格填充至最大长度(有var前缀的,表示是实际存储空间是变长的,而char 是定长的)。 VARCHAR2最多可以存储4,000字节的信息。
  • nvarchar2 :这是一个包含UNICODE格式数据的变长字符串。 NVARCHAR2最多可以存储4,000字节的信息。

数字类型

  • number: number(P,S), 需要1~22字节(BYTE)不等的存储空间 ,P表示有效数字的位数,最多不能超过38个有效数字。S(Scale)为正数时,表示从小数点到最低有效数字的位数,它为负数时,S表示从最大有效数字到小数点的位数
  • integer : 是number的子类型, 等同于NUMBER(38,0),用来存储整数。若插入、更新的数值有小数,则会被四舍五入。
  • binary_float : 是 32 位、 单精度浮点数字数据类型。
  • binary_double: 是为 64 位,双精度浮点数字数据类型。
  • float :Float(n), 也是number的子类,,数 n 指示位的二进制精度,,n 乘以 0.30103成为十进制,算上整数位一共保留 n*0.3 位 ,比如333 保留两位会变成 330, 3.333会变成 3.3

日期类型

  • date : 为每个日期值,Oracle 存储以下信息: 世纪、 年、 月、 日期、 小时、 分钟和秒。一般占用7个字节的存储空间
  • timestamp: 这是一个7字节或12字节的定宽日期/时间数据类型。它与DATE数据类型不同,因为TIMESTAMP可以包含小数秒,带小数秒的TIMESTAMP在小数点右边最多可以保留9位
  • TIMESTAMP WITH TIME ZONE : 略
  • TIMESTAMP WITH LOCAL TIME ZONE: 略
  • INTERVAL YEAR TO MOTH: 略
  • INTERVAL DAY TO SECOND: 略

LOB类型

内置的LOB数据类型包括 BLOB、CLOB、NCLOB、BFILE(外部存储)的大型化和非结构化数据,如文本、图像、视屏、空间数据存储。

  • blob : 它存储非结构化的二进制数据大对象,它可以被认为是没有字符集语义的比特流,一般是图像、声音、视频等文件。BLOB对象最多存储(4 gigabytes-1) * (database block size)的二进制数据。
  • clob: 它存储单字节和多字节字符数据。支持固定宽度和可变宽度的字符集。CLOB对象可以存储最多 (4 gigabytes-1) * (database block size) 大小的字符
  • nclob: 它存储UNICODE类型的数据
  • bfile: 二进制文件,存储在数据库外的系统文件,只读的,数据库会将该文件当二进制文件处理

LONG RAW & RAW 类型

  • long :它存储变长字符串,最多达2G的字符数据(2GB是指2千兆字节, 而不是2千兆字符),与VARCHAR2 或CHAR 类型一样,存储在LONG 类型中的文本要进行字符集转换。ORACLE建议开发中使用CLOB替代LONG类型。支持LONG 列只是为了保证向后兼容性。CLOB类型比LONG类型的限制要少得多。
  • long raw: 用于存储二进制或字符类型数据,变长二进制数据类型,这说明采用这种数据类型存储的数据不会发生字符集转换。这种类型最多可以存储2,000字节的信息

ROWID & UROWID 类型

rowid是oracle中的一个重要的概念。用于定位数据库中一条记录的一个相对唯一地址值。通常情况下,该值在该行数据插入到数据库表时即被确定且唯一。ROWID它是一个伪列,它并不实际存在于表中。它是ORACLE在读取表中数据行时,根据每一行数据的物理地址信息编码而成的一个伪列。所以根据一行数据的ROWID能找到一行数据的物理地址信息。从而快速地定位到数据行。数据库的大多数操作都是通过ROWID来完成的,而且使用ROWID来进行单记录定位速度是最快的。

create table DEMO_USER
(
    USER_ID             NUMBER(9,0)          not null,  
    USER_NAME           VARCHAR2(20)        not null,
    STATE               CHAR(1)              not null,
    CREATE_DATE         DATE                 not null,
    STATE_DATE          DATE                 not null,
    EMAIL               VARCHAR2(20)        not null,
    constraint EMAIL UNIQUE (EMAIL), constraint PK_DEMO_USER primary key (USER_ID)
)

create table DEMO_USER_DETAIL
(
    USER_ID                 NUMBER(9,0)          not null,
    USER_D1                 NUMBER(9,2)          , #小数位两位精度
    USER_D2                 float(4)          ,  #仅保留两位精度
    USER_D3                 date          ,
    USER_D4                 CHAR(1)          ,
    USER_D5                 VARCHAR2(20)          ,
    constraint PK_DEMO_USER_DETAIL primary key (USER_ID),
    CONSTRAINT FK_USER_ID FOREIGN KEY(USER_ID) REFERENCES DEMO_USER(USER_ID)
)

create table DEMO_RESOURCE
(
    RESOURCE_ID         NUMBER(9,0)          not null, 
    RESOURCE_NAME       VARCHAR2(20)        not null,
    USER_ID             NUMBER(9,0)          not null,
    RESOURCE_D1                 NUMBER(9,2)          ,
    RESOURCE_D2                 float(4)          , 
    RESOURCE_D3                 date          ,
    RESOURCE_D4                 CHAR(1)          ,
    RESOURCE_D5                 VARCHAR2(20)          ,
    constraint PK_RESOURCE_ID primary key (RESOURCE_ID),
    constraint FK_DEMO_RESOURCE_USER_ID FOREIGN KEY(USER_ID) REFERENCES DEMO_USER(USER_ID)
)

5 插入小规模模拟数据

全部查询并按ID排序:

select a.*,rowid from DEMO_USER a order by USER_ID;
select a.*,rowid from DEMO_USER_DETAIL a order by USER_ID;
select a.*,rowid from DEMO_RESOURCE a order by RESOURCE_ID;

插入单条数据:

INSERT INTO DEMO_USER 
(USER_ID, USER_NAME, STATE, CREATE_DATE, STATE_DATE, EMAIL) 
VALUES 
(1, 'user1', 'A', TO_DATE('2020-04-09 20:20:59', 'YYYY-MM-DD HH24:MI:SS'), 
TO_DATE('2020-04-09 20:20:59', 'YYYY-MM-DD HH24:MI:SS'), 
'adminExample@163.com');

INSERT INTO DEMO_USER_DETAIL
(USER_ID, USER_D1, USER_D2, USER_D3, USER_D4, USER_D5) 
VALUES 
(1, 100001, 3.33, TO_DATE('2020-06-09 20:20:59', 'YYYY-MM-DD HH24:MI:SS'), 'A','desc1');

INSERT INTO DEMO_RESOURCE
(RESOURCE_ID, RESOURCE_NAME, USER_ID, RESOURCE_D1, RESOURCE_D2, RESOURCE_D3, RESOURCE_D4, RESOURCE_D5) 
VALUES 
(10001, 'res1', 1, 500001, 6.66, TO_DATE('2020-06-09 20:20:59', 'YYYY-MM-DD HH24:MI:SS'), 'A','Rdesc1');

写个循环插入一百条类似的数据: 参考(https://blog.csdn.net/ck3207/article/details/78315843

思路

为了保证原表数据不变,创建两个 模拟表a 和 b,

把 原表 结构和数据拷贝给a,结构拷贝给b ;

循环修改 a 表数据;

把 a 表数据 插入 b表中 ;

最后得到的b表 即为 充满了模拟数据的表,数据量看循环的次数。

create table user_a as select * from DEMO_USER ;    #拷贝 DEMO_USER表及其数据到user_a表 ,注意主/外键约束没有被拷贝
create table user_b as select * from DEMO_USER  where 1 = 2;   #拷贝 DEMO_USER表到user_b表

declare
  i Integer;
begin
  i := 2;
  while i <= 100 loop
		update user_a  a 
			set 
			a.USER_ID= i, 
			a.USER_NAME= 'admin'||lpad(to_char(i),4,'0'),
			a.STATE= 'A',
			a.CREATE_DATE= (select sysdate+i from dual),
			a.STATE_DATE=  (select sysdate+i+10 from dual),
			a.EMAIL= '@163.com'||lpad(to_char(i),4,'0');
		insert into user_b 
			select * from user_a;
		i := i + 1;
		commit;
  end loop;
  commit;
end;

#增加一些异常的 state 字段
update user_b set STATE = 'B' where USER_ID > 90;
update user_b set STATE = 'C' where USER_ID > 40 and USER_ID < 50;

select a.*,rowid from user_a a order by USER_ID;
select a.*,rowid from user_b a order by USER_ID;

#其他两表进行一样的操作
create table USER_DETAIL_a as select * from DEMO_USER_DETAIL ;    
create table USER_DETAIL_b as select * from DEMO_USER_DETAIL  where 1 = 2;  

declare
  i Integer;
begin
  i := 2;
  while i <= 100 loop
		update USER_DETAIL_a  a 
			set 
			a.USER_ID= i, 
			a.USER_D1= (i + 100000)/3,
			a.USER_D2= i/9,
			a.USER_D3= (select sysdate+i+8 from dual),
			a.USER_D4=  'A',
			a.USER_D5= 'desc'||lpad(to_char(i),4,'0');
		insert into USER_DETAIL_b 
			select * from USER_DETAIL_a;
		i := i + 1;
		commit;
  end loop;
  commit;
end;

#另一张表
create table RESOURCE_a as select * from DEMO_RESOURCE ;    
create table RESOURCE_b as select * from DEMO_RESOURCE  where 1 = 2;  

declare
  i Integer;
begin
  i := 2;
  while i <= 100 loop
		update RESOURCE_a  a 
			set 
      a.RESOURCE_ID= i + 10000, 
      a.RESOURCE_NAME= 'resname'||lpad(to_char(i),4,'0'),
			a.USER_ID= i, 
			a.RESOURCE_D1= (i + 5000)/3,
			a.RESOURCE_D2= i/7,
			a.RESOURCE_D3= (select sysdate+i+7 from dual),
			a.RESOURCE_D4=  'A',
			a.RESOURCE_D5= 'desc'||lpad(to_char(i),4,'0');
		insert into RESOURCE_b 
			select * from RESOURCE_a;
		i := i + 1;
		commit;
  end loop;
  commit;
end;
select a.*,rowid from RESOURCE_b a order by USER_ID desc; 

6 基础,简单的SQL

=========一些资料 =========

SQL的功能:

  • 面向数据库执行查询
  • 可从数据库取回数据
  • 可在数据库中插入新的记录
  • 可更新数据库中的数据
  • 可从数据库删除记录
  • 可创建新数据库
  • 可在数据库中创建新表
  • 可在数据库中创建存储过程
  • 可在数据库中创建视图
  • 可以设置表、存储过程和视图的权限

数据定义语言 (DDL)

  • CREATE DATABASE - 创建新数据库
  • ALTER DATABASE - 修改数据库
  • CREATE TABLE - 创建新表
  • ALTER TABLE - 变更(改变)数据库表
  • DROP TABLE - 删除表
  • CREATE INDEX - 创建索引(搜索键)
  • DROP INDEX - 删除索引

=========一些资料 over =========

增删改查: select ;delete; update; insert ;like; regexp_like ;row_id ;where ;or ;and; distinct

#查, 带 row_id 的全查,降序(desc)排列
select a.*,rowid from user_b a order by USER_ID desc;  
#查,查部分(USER_ID  和 state)字段,字段重命名, state 字段为A或者C,且字段ID 小于 10 
select USER_ID as ID , state from user_b where STATE = 'C' or STATE = 'A' and USER_ID < 10; 

# distinct    # 返回唯一不同的值
select distinct state from user_b ;

#增, 新增数据
INSERT INTO user_b 
(USER_ID, USER_NAME, STATE, CREATE_DATE, STATE_DATE, EMAIL) 
VALUES 
(1, 'Fuser1', 'A', TO_DATE('2020-04-09 20:20:59', 'YYYY-MM-DD HH24:MI:SS'), 
TO_DATE('2020-04-09 20:20:59', 'YYYY-MM-DD HH24:MI:SS'), 
'adminExample@163.com');

#改, 带条件的修改 (比如正则匹配) ,regexp_like ,以 F1 或 Fu开头的,i是不区分大小写
update user_b set state = 'B' where regexp_like(USER_NAME,'^F[1u]','i');

#删, 
delete user_b  where use_id = 99;

# 增
INSERT INTO user_b 
(USER_ID, USER_NAME, STATE, CREATE_DATE, STATE_DATE, EMAIL) 
VALUES 
(99, 'Fuser99', 'A', TO_DATE('2020-04-09 20:20:59', 'YYYY-MM-DD HH24:MI:SS'), 
TO_DATE('2020-04-09 20:20:59', 'YYYY-MM-DD HH24:MI:SS'), 
'adminExample@163.com');

where 中 的 in ;not in ; like; between ; < ; > ;

# in , not in ,略 
UPDATE RESOURCE_b set RESOURCE_D4 = 'B' where user_id in (99,97,96) ;

#复杂的正则表达式懒得说了,不常用就忘了,没办法
# like ,%3表示 以3结尾  ,如 3 ,13,23 ......
UPDATE RESOURCE_b set RESOURCE_D4 = 'C' where user_id like '%3' ;
select a.*,rowid from RESOURCE_b a where a.RESOURCE_D4 = 'C' order by USER_ID desc; 

# between , 数字,时间 属于某一区间
select * from user_b where user_id between 8 and 20;
select * from user_b where CREATE_DATE between 
TO_DATE('2020-06-27 20:20:59', 'YYYY-MM-DD HH24:MI:SS') and 
TO_DATE('2020-07-27 20:20:59', 'YYYY-MM-DD HH24:MI:SS');

 

top TOP 子句用于规定要返回的记录的数目。 对于拥有数千条记录的大型表来说,TOP 子句是非常有用的。

rownum : oracle 不支持 top ,一般用 rownum 代替实现 ,rownum 是按照表数据插入时间 排的 ,当然我们也可以自定义升/降排序

rownum=1 可以查询第一条数据

rownum < n(n>1的自然数) 可以查询

rownum = n(n>1的自然数) 不可以查询

rownum > n(n>1的自然数) 不可以查询 ,必须使用子查询

rownum在某区间的数据,必须使用子查询 。

子查询 中的rownum必须要有别名 ,因为rownum不是某个表的列,如果不起别名的话,无法知道rownum是子查询 的列还是主查询 的列 。

row_number 也能用

select * from user_b  where rownum=1;
select * from user_b  where rownum < 32;

select * from (select rownum no ,user_id ,user_name from user_b where rownum<=3 ) where no >=2;

select * from (select user_id ,row_number() over ( order by user_id desc ) rn from user_b ) 
 where rn between 4 and 10;

别名

select a.*,rowid from user_b a order by USER_ID desc;  

#别名不用as 直接在 后面空格 别名即可
#下面的关联查询 ,会将 b1 的每个结果 分别和 b2 的每个结果匹配
SELECT b1.user_id, b2.USER_D5 FROM user_b b1, USER_DETAIL_b b2
WHERE b1.user_id < 4 AND b2.user_id >97;

关联查询:

  • from XX (inner ) join XXX on ...: 如果表中有至少一个匹配,则返回行
  • left join : 即使右表中没有匹配,也从左表返回所有的行
  • right join : 即使左表中没有匹配,也从右表返回所有的行
  • full join : 只要其中一个表中存在匹配,就返回行

 

#a 表id 有1-100  ,b 表id有2-100 ,且 40-50 被缺少(被删了)
delete from USER_DETAIL_b where user_id > 40 and user_id < 50;

#inner join ,取交集
SELECT a.user_id, a.user_name,  b.USER_D5 
FROM user_b a INNER JOIN USER_DETAIL_b b ON a.user_id = b.user_id;

#left join ,取交集 + 左边剩余的全集   ,注意,由于有一些 user_id  在 b中没有,所以其对应的 b.USER_D5  就是 null
SELECT a.user_id, a.user_name,  b.USER_D5 
FROM user_b a left JOIN USER_DETAIL_b b ON a.user_id = b.user_id;

UNION

union all :合并并允许重复值

union : 合并并合并重复值

UNION 操作符用于合并两个或多个 SELECT 语句的结果集。UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同。

select * from user_b where user_id < 10
union
select * from user_b where user_id > 90;

创建索引

在不读取整个表的情况下,索引使数据库应用程序可以更快地查找数据。即:索引是(帮助快速获取数据的)数据结构。

在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构,就是索引。

更新一个包含索引的表需要比更新一个没有索引的表更多的时间,这是由于索引本身也需要更新。因此,理想的做法是仅仅在常常被搜索的列(以及表)上面创建索引

聚类索引 clustered index :类似于 按读音查字典

非聚类索引 nonclustered index : 类似于 按偏旁部首查字典

CREATE UNIQUE INDEX index_user_id ON user_b (user_id);
CREATE INDEX index_res_id ON resource_b(resource_id);

一些函数:

where 语句中不能出现聚合函数

select avg(user_id) from user_b ;                  #返回某列的平均值
select count(user_id) from user_b ;                #返回某列的行数(不包括 NULL 值)
select count(*) from user_b ;                      #返回被选行数
select first(user_id) from user_b ;                #first   ,在 Oracle中不支持
select last(user_id) from user_b ;                 #last    ,在 Oracle中不支持
select max(user_id) from user_b ;                  #max
select min(user_id) from user_b ;                  #min
select sum(user_id) from user_b ;                  #返回某列的总和

group by

group by一般和 操作函数 一起使用例如max、min、sum、avg、count等一块用

group by是对检索结果(非操作函数列) 进行分组,然后每一个分组执行操作函数。

order by 的列要是group by 的子列,因为order by 是对group by 的排序进行再排序,所以order by的列要在group by中出现

 

#修改下数据,方便测试
update resource_b set user_id = 5 where resource_id < 10005;
update resource_b set user_id = 6 where resource_id > 10005 and resource_id < 10010;

#先按照 select的部分分组,然后执行 sum, 然后重命名成 sumValue
select user_id , SUM(resource_d2) sumValue
FROM resource_b where resource_id < 10012 
group by user_id;

#先按照 select的部分分组,有两个,所以是user_id+ resource_name 合起来唯一的为一组,
#然后执行 sum,
select user_id ,resource_name, SUM(resource_d2) 
FROM resource_b where resource_id < 10012 
group by user_id,resource_name;

having

在 SQL 中增加 HAVING 子句原因是,WHERE 关键字无法与合计函数一起使用。

当在gropuby子句中使用having子句时,查询结果中只返回满足having条件的组。在一个sql语句中可以有where子句和having子句。having与where子句类似,均用于设置限定条件

where子句的作用是在对查询结果进行分组前,将不符合where条件的行去掉,即在分组之前过滤数据,条件中不能包含聚组函数,使用where条件显示特定的行。

having子句的作用是筛选满足条件的组,即在分组之后过滤数据,条件中经常包含聚组函数,使用having条件显示特定的组,也可以使用多个分组标准进行分组。

WHERE语句在GROUPBY语句之前;SQL会在分组之前计算WHERE语句。

HAVING语句在GROUPBY语句之后;SQL会在分组之后计算HAVING语句。

#这里查出来有四列
select user_id , SUM(resource_d2) d2, SUM(resource_d1)  FROM resource_b where resource_id < 10012 group by user_id;

#加了两个 having 限制,只剩两列了,  注意 having 不能用操作函数结果的别名
select user_id , SUM(resource_d2)  , SUM(resource_d1)   FROM resource_b where resource_id < 10012 
group by user_id 
having SUM(resource_d2) > 1.5 and SUM(resource_d1) > 2000;

序列 sequence

#创建序列
create sequence user_id_seq
minvalue 1500
maxvalue 999999
start with 1500
increment by 1

#查看所有序列
SELECT * FROM user_objects ubs where ubs.OBJECT_TYPE = 'SEQUENCE' ORDER BY object_name;

#查询下一个序列值
select user_id_seq.nextval from dual;

触发器

表(user_b) 的某个用户(user_id =1)的 state(CHAR(1))应该永远为 'A',我们意外update 了,那么触发器也可以自动触发改回去.

注意下面这个触发器是不建议乱加的,很明显在 update on user_b 就会触发一次,浪费性能。

create or replace trigger Unlock_user_1
after update on user_b
declare
  vLockFlag char(1);
begin
  select state into vLockFlag from user_b where user_id = 1;
  if vLockFlag != 'A' then
     update user_b set state = 'A' where user_id = 1;
  end if;
end Unlock_user_1;

select * from user_b where user_id < 10;
update user_b set state = 'C' where user_id = 1;

系统时间,时间格式转换;

string 改成 时间格式

SELECT * FROM user_b where create_date BETWEEN
       to_date('2020-06-21 10:50:51', 'yyyy-mm-dd hh24:mi:ss') and
       to_date('2020-06-30 10:50:51', 'yyyy-mm-dd hh24:mi:ss') ;

date 改成 String

SELECT * FROM user_b where to_char(create_date ,'yyyy-mm-dd hh:mi:ss') BETWEEN
       '2020-06-21 10:50:51'and '2020-06-30 10:50:511' ;

分页查询

MySQL分页:limit

这是一段Java接口 ,把一个 SQL 包装成分页SQL并返回 ,这个效率比较差,是最简单版本,以可用索引检索等来提高效率

public static String MySQLPageSQL(String sql, int pageSize, int pageNum) {
    int endNum = pageSize * pageNum;
    int startNum = pageSize * (pageNum - 1);
    String end = "limit" + startNum + "," + endNum;
    return sql + end;
}

例子 sql (我机器没有MySql ,所以这条我没有验证)

SELECT * FROM user_b limit 100 , 200

Oracle 分页:rwonum

同样的给出一个Java接口 ,这个效率还不错,我看过一些框架用的就是这法子,我自己实现了一下

public static String OraclePageSQL(String sql, int pageSize, int pageNum) {
    String result;
    try {
        int endNum = pageSize * pageNum;
        int startNum = pageSize * (pageNum - 1);
        String front = "SELECT * FROM (SELECT TMP_PAGE.*, ROWNUM ROW_ID FROM (";
        String end = ")TMP_PAGE WHERE ROWNUM <=" + endNum + ") WHERE ROW_ID > " + startNum;
        result = front + sql + end;
        logger.info("OraclePageSQL ret is {}", result);
        return result;
    }
    catch (RuntimeException e) {
        logger.info("OraclePageSQL failed! ret no page sql");
        return sql;
    }
}
SELECT * FROM (SELECT TMP_PAGE.*, ROWNUM ROW_ID FROM (
SELECT * from user_b 
) TMP_PAGE WHERE ROWNUM <= 60) WHERE ROW_ID > 40;

存储过程

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页

打赏作者

Clark Kent 2000

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值