oracle 插入含&字符串

1、创建表
SQL> create table t(id number,name varchar2(20));

表已创建。

2、常规方式插入
SQL> insert into t values(1,’a&b’);
输入 b 的值: a&b
原值 1: insert into t values(1,’a&b’)
新值 1: insert into t values(1,’aa&b’)

已创建 1 行。

3、chr(38)插入
SQL> insert into t values(2,’c’||chr(38)||’d’);

已创建 1 行。

4、set define
SQL> set define `
SQL> insert into t values(3,’e&f’);

已创建 1 行。

5、查看结果
SQL> select * from t;

ID NAME
———- ——————–
1 aa&b
2 c&d
3 e&f

6、说明
第一种方法不能得到正常的,我想要的结果,而且第一种方法在应用程序中也比较难实现
第二种比较适合应用程序实现
第三种比较适合sqlplus进行批量处理数据

GREATEST/LEAST函数

GREATEST
greatest( expr1, expr2, … expr_n )
expr1, expr2, . expr_n 可以是值也可以是函数.
函数功能: 取得值最大值

SQL> SELECT GREATEST(10,21,3,15,18) FROM dual;

GREATEST(10,21,3,15,18)
———————–
21
SQL> SELECT GREATEST(‘abc’,’bca’,’cba’,’bac’,’cabb’,’cbaa’) FROM dual;

GREATEST(‘ABC’,’BCA’,’CBA’,’BA
——————————
cbaa

LEAST
least( expr1, expr2, … expr_n )
expr1, expr2, . expr_n 可以是值也可以是函数.
函数功能: 取得值最小值

SQL> SELECT least(10,21,3,15,18) FROM dual;

LEAST(10,21,3,15,18)
——————–
3
SQL> SELECT least(‘abc’,’bca’,’cba’,’a’,’bac’,’cabb’,’cbaa’) FROM dual;

LEAST(‘ABC’,’BCA’,’CBA’,’A’,’B
——————————
a

oracle分割函数

1、创建varry

CREATE OR REPLACE TYPE Varchar2Varray IS VARRAY(100) of VARCHAR2(40);

2、创建分割函数

CREATE OR REPLACE FUNCTION f_strsplit (STRING VARCHAR2, substring VARCHAR2)
   RETURN varchar2varray
IS
   len       INTEGER        := LENGTH (substring);
   lastpos   INTEGER        := 1 - len;
   pos       INTEGER;
   num       INTEGER;
   i         INTEGER        := 1;
   ret       varchar2varray := varchar2varray (NULL);
   v_str     VARCHAR2 (20);
 /**自定义split函数,将指定的字符串按指定的标志符分割成字符数组*/
BEGIN
   LOOP
      pos := INSTR (STRING, substring, lastpos + len);

      IF pos > 0
      THEN                                                            --found
         num := pos - (lastpos + len);
      ELSE                                                         --not found
         num := LENGTH (STRING) + 1 - (lastpos + len);
      END IF;

      IF i > ret.LAST
      THEN
         ret.EXTEND;
      END IF;

      v_str := SUBSTR (STRING, lastpos + len, num);
      --DBMS_OUTPUT.put_line (v_str);

      ret(i) := v_str;

      EXIT WHEN pos = 0;
      lastpos := pos;
      i := i + 1;
   END LOOP;

   RETURN ret;
END;

3、调用

select * from tab_dailyreport_user where user_id in (
  SELECT * FROM 
( TABLE( select f_strsplit(user_invite,',')
                        from tab_dailyreport_user t
                       where t.user_id = 168148)));

说明:主要是改写开发提过来的一个sql语句的帮助

select * from tab_dailyreport_user where user_id in (
--'166445','164216','171128','184427','160113','160133','160134','160138','160144','160163','160587','166457','167914','168076','168192','168997','169842','169901','184407','184747','185089','185130','208134','208141','208143','208183','160142','166455','167838','168074','168194','168666','185088','185138','185145','208103','169844','171071','160107','166421','166874','168193','179871','179872','184096','184228','184232','184269','184774','184969','185111','207871','160167','161813','14880','134','164355','168149')
select substr(regexp_replace,3,length(regexp_replace)-4) from (
select regexp_replace((select user_invite
                        from tab_dailyreport_user t
                       where t.user_id = 168148),
                      '(,)',
                      chr(39)||','||chr(39)) regexp_replace
  from dual) )

括号里面的语句查询出来的结果是注释部分,直接使用注释的部分在in中可以查询,如果使用里面的语句不能查询,他们的需求是想把外面的user_id在里面的语句中的,可是oracle会把里面的in查询出来的结果作为一个整体,从而出现number类型不能和varchar类型匹配的提示,采用方法是分割in里面查询出来的语句,然后类型转换为table进行查询。

关于日期sql语句

网友请求写几条关于日期的sql语句
1、查询两个日期天数
select trunc(to_date(to_date( ‘2004-3-20 ‘, ‘yyyy-mm-dd ‘)-to_date( ‘2004-3-25 ‘, ‘yyyy-mm-dd ‘),’mm’) ) from dual ;
–trunc函数不用也行,因为日期格式化就是到天

2、查询两个日期的月份
SELECT trunc(months_between(to_date( ‘2004-3-20 ‘, ‘yyyy-mm-dd ‘),SYSDATE)) FROM dual;
–根据需求是截断还是取近似值决定使用floor或者trunc

3、根据生日查询年龄
1)计算年龄(周岁)
select floor(months_BETWEEN(SYSDATE,to_date( ‘2004-4-25 ‘, ‘yyyy-mm-dd ‘))/12) FROM dual;
2)计算年龄(虚岁)
SELECT to_char(SYSDATE,’yyyy’)-to_char(to_date(‘2004-03-04′,’yyyy-mm-dd’),’yyyy’) FROM dual;

主要就是trunc(近似值)和floor(截断)函数使用

lag() lead()函数使用

1、语法
LAG (value_expression [,offset] [,default]) OVER ([query_partition_clause] order_by_clause)
LEAD (value_expression [,offset] [,default]) OVER ([query_partition_clause] order_by_clause)

2、说明
1)lag 和lead 可以 获取结果集中,按一定排序所排列的当前行的上下相邻若干offset 的某个行的某个列(不用结果集的自关联)
2)lag 和lead 有三个参数,第一个参数是列名,第二个参数是偏移的offset,第三个参数是超出记录窗口时的默认值
3)lag ,lead 分别是向前,向后

3、准备试验环境

CREATE TABLE t(t_NAME VARCHAR2(10),t_order NUMBER);
INSERT INTO t VALUES('aaaa',1);
INSERT INTO t VALUES('bbbb',2);
INSERT INTO t VALUES('cccc',3);
INSERT INTO t VALUES('dddd',6);
INSERT INTO t VALUES('eeee',4);
INSERT INTO t VALUES('ffff',5);
SELECT * FROM t;
T_NAME        T_ORDER
---------- ----------
aaaa                1
bbbb                2
cccc                3
dddd                6
eeee                4
ffff                5
6 rows selected

4、测试

SELECT T_ORDER,
LAG(T_NAME, 1,'lag_fei') OVER(ORDER BY T_ORDER) "LAG",
T_NAME,
LEAD(T_NAME, 1,'lead_fei') OVER(ORDER BY T_ORDER)"LEAD"
FROM T
ORDER BY T_ORDER;

T_ORDER LAG        T_NAME     LEAD
---------- ---------- ---------- ----------
1 lag_fei    aaaa       bbbb
2 aaaa       bbbb       cccc
3 bbbb       cccc       eeee
4 cccc       eeee       ffff
5 eeee       ffff       dddd
6 ffff       dddd       lead_fei
6 rows selected