ORACLE提供可以把PL/SQL程序存储在数据库中,并可以在任何地方运行他,这样就叫做存储过程或者函数,意思就说白了,就是你之前写的select,什么update,这些东西存储起来,我想把这些操作存储起来,像表,视图,结构式的,当然他不是对象,这里不叫对象,他也能够存储起来,像Function,这是系统提供的,你自己创建的,之前写过,我们可以删掉他,这儿说明他确确实实存在,包括像这个触发器,这里没有,说明没有创建,当你创建一个函数,存储过程的时候,那就能够保存下来,什么时候想调用,就调用就完了,触发器,当你想对某个表进行操作的时候,也是类似于一个函数的东西,这个时候叫做触发器,自动的触发他,就是这样,它是可以被保存起来的,过程和函数的唯一区别就是函数总是向调用者返回数据,而过程不返回数据,相当于一个有返回值,一个没有,函数是有的,过程是没有的

创建create or replace function,跟前面写的视图都一样,然后这个function的名,如果有参数的话,后边写上他整个的参数类型,这相当于是一个小括号,function涉及到的形参一样,形参你写到这里边,先写一个参数名,再写参数类型,这里就不需要指定一个参数的大小了,仅仅是几个类型就行,这个形参什么时候给你填进去,就是通过declare语句,我们上午讲了declare,begin,在begin;里面调用这个函数的时候,参数是什么,return紧接着就是你返回函数的返回值类型,然后这个叫is,is里面操作的你可以把它假象成,加上declare,函数在整个的使用当中,你需要定义一个变量,你就定义到这儿,再是你这个函数的执行体,如果有异常的话,我给你写的这个结构,函数的结构

存储函数,这个结构怎么写,他就是create or replace function,取个function名,就写func_name,括号写上你参数的类型,参数类型,id number类型的,逗号,name,你想查指定表当中的id,这个id,这个名字的那个人,等等,或者你想查一下id这个人的工资,salary也是number类型的,往那放,这里又具体分,讲什么out,一会说到这再说,这是定义这个函数,然后他return,返回值类型,假设你要返回,这里不写这个id,写dept_id,我返回指定部门的,所有的工资,指定部门可能有很多人,这些所有人的工资,return也是工资,工资是number类型的,你就返回number类型的,然后is,你在这个过程当中,是不是再涉及到你要定义一些变量,如果需要的话,你写在is这一块,就是函数的使用过程中,需要声明的变量,或者叫记录类型,写在这,声明一个变量,记录类型,甚至还可以是游标,游标就写在这,然后呢,begin,开始,这是函数的执行,函数的执行体,在这个过程当中,出现一个异常,考虑异常的处理,处理函数处理过程中的异常,处理完了以后,就给他end,这是存储函数的一个过程,这里相当于declare,我们写一个PL/SQL的时候,declare begin end,你就把他当成declare,就是在声明函数中调用到的变量,这是函数的一个形参,这样创建好以后,他就有这个了,有这个function以后,大概形式就是这样create or replace function func_name(dept_id number,salary number)return number;isbeginexceptionend;

22.2 返回一个"helloworld: atguigu"的字符串,其中atguigu 由执行函数时输入。--函数的声明(有参数的写在小括号里)
create or replace function hello_func(v_logo varchar2)
--返回值类型
return varchar2
is
--PL/SQL块变量的声明
begin
--函数体return 'helloworld'|| v_logo;
end;这就是这个函数的作用,函数的helloworld,调用这个函数就返回hellworld,看他怎么写,create or replace function,叫hello_world,这个函数没有形参,返回helloworld这个字符串,return varchar2,不用写那个什么,不用写分号,也不用写大小,is声明,也不用声明,直接begin,return,这是你函数的执行体,执行后的结果,因为你这个函数是需要有返回值的,我就在这里给你返回,没有异常,没有就end,这是一个最简单的存储函数,创建了create or replace function hello_worldisbeginreturn "helloworld";end;

创建以后我们在这看,这里就有一个hello_world

正常来写,declare什么什么,这里也不用declare,直接begin,dbms_output.put_line,调用你hello_world这个函数,end,这就出来了begindbms_output.put_line(hello_world);end;

或者你在这使用select语句也行,select hello_world,from dualselect hello_world from dual;

这就是具体调用这个函数了,这是这个例子,然后我把它写得复杂一点,给这个函数带上一个参数,hello_world1,带个参数,什么参数,加上一个v_log,它是一个varchar2类型的,返回他这个varchar2,然后is是声明,声明写到这里也行,变量的声明,这里不需要变量声明,这个变量已经有了不需要声明,begin,v_log他赋一个值,直接return,这里我定义了一个形参,相当于,然后呢走到这,创建好了create or replace function hello_world1(v_logo varchar2)return varchar2isbeginreturn 'helloworld' || v_logo;end;

然后这个调用,select就这么写,select hello_world1,这个参数,varchar型的,他,from他select hello_world1('atguigu') from dual;

这是select,如果你想使用PL/SQL句型的话,那你就这样begindbms_output.put_line(hello_world('atguigu'));end;

一种是使用PL/SQL程式的形式,一种是SELECT的形式,关键是你要会写这个,这个格式,创建一个函数,函数名,函数是否需要参数,需要的话就需要写上一个参数,参数的话只要指明类型就行,函数一定是有返回值的,一定会return一个东西,然后函数在使用过程中,是否需要声明一些变量,相当于在JAVA里边,方法里边,局部变量,起在is和begin之间,你也可以把它理解成declare,我们之前写在declare和begin之间的东西可以写在这儿,begin,你这个函数具体执行的函数体,结束,一定要记住这,那这儿你也可以加上一个输出语句,这里or replace相当于把它替换了create or replace function hello_world1(v_logo varchar2)return varchar2isbegindbms_output.put_line('人家是函数啦,么么哒');return 'helloworld' || v_logo;end;

select hello_world1('atguigu1') from dual;

就相当于他执行这个函数体,你这个传入的就放到这儿了,跟你讲JAVA的情况一样,实际上你声明一个值,给我传一个值,调用你传入的这个值,就是这个意思,这个你看返回的这个顺序,你看它是先输出的这个,再打印的这个,因为它是有返回值的,他select先拿到你这个返回值,然后返回完了以后,你要这样写的话,或者说有两种执行方式,另一种begindbms_output.put_line(hello_world1('atguigu'));end;

这个先输出的这个,是按照你的顺序,这个你了解一下就行,重点是你如何来定义这个函数,这个函数就这样,然后我们看别的例题22.3 创建一个存储函数,返回当前的系统时间
create or replace function func1
return date
is
--定义变量
v_date date;
begin--函数体--v_date := sysdate;select sysdate into v_date from dual;dbms_output.put_line('我是函数哦');return v_date;
end;执行法1:
select func1 from dual;
执行法2:
declarev_date date;
beginv_date := func1;dbms_output.put_line(v_date);
end;创建一个存储函数,返回当前的系统时间,这个就是函数的作用,create or replace function,get_sysdate,这是他的函数名,return是一个date类型的,然后is需要声明变量吗,声明一个也行,声明一下就这样,date类型的,这个不需要指明大小,begin,可以这样写,v_date := sysdate,然后呢,然后return date,没有异常,直接end,这样写create or replace function get_sysdatereturn dateisv_date date;beginv_date := sysdate;return v_date;end;

然后你在这执行一个select get_sysdate from dual;

23. 定义带参数的函数: 两个数相加create or replace function add_func(a number, b number)
return number
is
beginreturn (a + b);
end;执行函数begindbms_output.put_line(add_func(12, 13));
end;
或者select add_func(12,13) from dual;定义带参数的函数,create or replace function,add,add相加的意思,两个参数相加,定义v_num1,number类型的,v_num2,还是number类型,return返回number类型的,is需要再声明一个变量不,v_sum计算他们的和,number类型的,指明10个,begin,v_sum等于v_num1加上v_num2,return v_sumcreate or replace function add add_param(v_num1 number,v_num2 number)return numberisv_sum number(10);beginv_sum := v_num1 + v_num2;return v_sum;end;

创建好了,这个,运行一下select add_param(2,4) from dual;

在这也行,这个就是使用PL/SQL块的形式begindbms_output.put_line(add_param(3,4));end;

24. 定义一个函数: 获取给定部门的工资总和, 要求:部门号定义为参数, 工资总额定义为返回值.create or replace function sum_sal(dept_id number)return numberiscursor sal_cursor is select salary from employees where department_id = dept_id;v_sum_sal number(8) := 0;
beginfor c in sal_cursor loopv_sum_sal := v_sum_sal + c.salary;end loop;       --dbms_output.put_line('sum salary: ' || v_sum_sal);return v_sum_sal;
end;执行函数begindbms_output.put_line(sum_sal(80));
end;定义一个函数,获取给定部门的工资总和,要求部门号定义为参数,工资总和定义为返回值,返回总额肯定需要你把一个人一个人的工资加起来,或者再准确点说,所有人都会把工资遍历一遍,使用游标吧,这就把刚才讲的给他结合起来了,function get_sal,dept_id,number类型的,返回值类型,number的,is,需不需要声明一个变量,声明sum工资,是一个number类型的,10,分号结束,然后begin,方法体怎么来写,我们现在这个时候再往下写,怎么求指定部门所有的和,使用一个游标,游标是不是又得写在当时的declare里,那你这个就写这儿呗,指定这个人的部门的工资,cursor给他创建完以后,你就得open,或者我用一个for更简单,让他加到这个里边,c.salary,这个你要先给他指定一个值,游标都不用关了,返回create or replace function get_sal(dept_id number)return numberisv_sumsal number(10) := 0;cursor salary_cursor is select salary from employees where department_id = dept_id;beginfor c in salary_cursor loopv_sumsal := v_sumsal + c.salary;end loop;return v_sumsal;end;

get_sal,select,get_sal,80号部门的select get_sal(80) from dual;

你要在这用declare也行,begin,dbmsdeclarev_deptid number(4) := 80;begindbms_output.put_line(get_sal(v_deptid));end;

25. 关于 OUT 型的参数: 因为函数只能有一个返回值, PL/SQL 程序可以通过 OUT 型的参数实现有多个返回值要求: 定义一个函数: 获取给定部门的工资总和 和 该部门的员工总数(定义为 OUT 类型的参数).
要求: 部门号定义为参数, 工资总额定义为返回值.create or replace function sum_sal(dept_id number, total_count out number)return numberiscursor sal_cursor is select salary from employees where department_id = dept_id;v_sum_sal number(8) := 0;
begintotal_count := 0;for c in sal_cursor loopv_sum_sal := v_sum_sal + c.salary;total_count := total_count + 1;end loop;       --dbms_output.put_line('sum salary: ' || v_sum_sal);return v_sum_sal;
end;   执行函数:delare v_total number(3) := 0;begindbms_output.put_line(sum_sal(80, v_total));dbms_output.put_line(v_total);
end;我们说函数,自变量可以有多个,但是函数返回值永远只有一个,这样才叫函数,这里为什么要定义一个out型的参数,因为我们知道return永远是return一个,但是我又想存储过程当中,除了要返回工资总额之外,我还想让你返回点别的,比如说这个,除了要你返回给定部门的工资总额之外,我还想看看这个部门有多少员工,那你这个一个函数,相当于两个返回值,一个是指定部门的工资总和,一个是该部门的员工总数,你要是变成两个function,那变成一个里面怎么去做,这个就要使用一个out型的参数,这个参数怎么用,我们就以他举例说一下,在这个里边也有一些说明,in默认不写的话他就是in,比如in,标记表示传递给函数的值,在该函数执行过程中不改变,你像我们80号部门的80,就是你在执行的过程当中,只要你用到这个变量了,他都是80,out标记表示一个值在函数中进行计算并通过该参数传递给调用语句,这个变量需要你在函数执行之前,来定义一下,而这个值是可以被改变的,我们就写一个这个例子,定义一个函数,获取给定部门的工资总额,和该部门的员工总数,把这个定义成一个out型的参数,部门号定义为参数,工资总额定义为返回值,那我们这个怎么写,定义一个函数,给定部门的工资总额和他,除了把它当做一个参数之外,还得给一个总人数,total_count,也是一个number类型的,然后为了表明他不是一个参数,你要这样写的话,那你调用这个函数,需要指定两个参数,不是一个参数,这个也是一个返回值,但是不是return出来的,加一个out,get_sal1,这个number是工资总和,is,工资总和为0,然后呢,cursor还是指向他,需要指明total_count还是一个值,一开始没有,所以他的值可以改变,赋值为0,这个是把它工资给累加起来,同时让他累加,还是返回工资总和,这个变量,就是在你计算工资总和的过程当中,不知不觉的把这个值给他,记录了一下,那么这个值就相当于记录到了,然后给他end结束,执行完了,create or replace function get_sal1(dept_id number,total_count out number)return numberisv_sumsal number(10) := 0;cursor salary_cursor is select salary from employees where department_id = dept_id;begintotal_count := 0;for c in salary_cursor loopv_sumsal := v_sumsal + c.salary;total_count := total_count + 1;end loop;return v_sumsal;end;

怎么用这个,多了一个,declare,我定义一个变量,number吧,我在这dbms,调用这个函数,前面是80号部门的,我让他去记录,这个先给他赋一个值先,这个打印的结果就是你这个的返回值,80号部门的工资,但是他把我这个值给记录下来了,那我这个时候打印我这个值先,这个是工资总和,这个是公司的人数declarev_num number(5) := 0;begindbms_output.put_line(get_sal(80,v_sum));dbms_output.put_line(v_num);end;

这个就是讲out变量怎么用,正常我们讲一个函数就一个返回值,这里同样也是一个,我就想在运算当中再给我算一个值,其实相当于在看一个因变量,是直接让你返回的,然后被记录下来了,我可以通过这种方式,让你在计算总工资的时候,把这个值给改变了,再后边就是存储过程,大家先把我讲的存储函数的给看一看,过程没有返回值,刚才我们讲的都是存储函数,函数是有返回值的,你把这个格式给记住一下,这是函数的格式,函数的格式有了,你再往里套,过程没有返回值了,这不叫function了,这个是面向过程26*. 定义一个存储过程: 获取给定部门的工资总和(通过 out 参数), 要求:部门号和工资总额定义为参数create or replace procedure sum_sal_procedure(dept_id number, v_sum_sal out number)iscursor sal_cursor is select salary from employees where department_id = dept_id;
beginv_sum_sal := 0;for c in sal_cursor loop--dbms_output.put_line(c.salary);v_sum_sal := v_sum_sal + c.salary;end loop;       dbms_output.put_line('sum salary: ' || v_sum_sal);
end;
[执行]
declare v_sum_sal number(10) := 0;
beginsum_sal_procedure(80,v_sum_sal);
end;获取给定部门的工资总和,然后部门号和工资总额定义为参数,那我写的时候把工资总额当成返回值了,是吧,他定义为参数,对应的用存储过程写,没有返回值,所以你只能用out,用out来写,set serveroutput on

这是刚才写的存储函数,然后现在让你写一个存储过程,给定部门的工资总额,然后create or replace,然后get_sal2,部门号这是作为一个参数,工资总额sumsal,out型的,也是number类型,没有return,is就不用再定义了,sumsal赋个值,添加进去以后,for循环完了以后,sumsal,end结束create or replace procedure get_sal2(dept_id number,sumsal out number)iscursor salary_cursor is select salary from employees where department_id = dept_id;beginsumsal := 0;for c in salary_cursor loopsumsal := sumsal + c.salary;end loop;dbms_output.put_line(sumsal);end;

创建好以后调用一下,你不是要传一个变量吗,80号部门,你要写一个变量,那你还得在PL/SQL写,declare,v_sal,number类型的,冒号等于,给一个初始化值,begin,80号部门的,把他放进去,end结束declarev_sal number(10) := 0;beginget_sal2(80,v_sal);end;

因为他没有返回值了,就像我们JAVA里面的函数,这就打印80号部门的工资总和,这个就是一个存储过程,你要是函数搞清楚了,存储过程,是比较简单的,把这个改一改,没有return,这里边也不要有return,一般里边都会有一个输出语句,或者你也不一定是输出了,也有可能是增删改,因为增删改是不需要返回的,增删改不需要返回,所以把增删改定义成一个存储过程27*. 自定义一个存储过程完成以下操作:
对给定部门(作为输入参数)的员工进行加薪操作, 若其到公司的时间在 (? , 95) 期间,    为其加薪 %5[95 , 98)             %3       [98, ?)               %1
得到以下返回结果: 为此次加薪公司每月需要额外付出多少成本(定义一个 OUT 型的输出参数).create or replace procedure add_sal_procedure(dept_id number, temp out number)iscursor sal_cursor is select employee_id id, hire_date hd, salary sal from employees where department_id = dept_id;a number(4, 2) := 0;
begintemp := 0;       for c in sal_cursor loopa := 0;    if c.hd < to_date('1995-1-1', 'yyyy-mm-dd') thena := 0.05;elsif c.hd < to_date('1998-1-1', 'yyyy-mm-dd') thena := 0.03;elsea := 0.01;end if;temp := temp + c.sal * a;update employees set salary = salary * (1 + a) where employee_id = c.id;end loop;
end;对于给定部门,把它作为一个参数,相当于对指定部门进行操作,进行加薪,既然没有返回值,如果你需要一些返回的情况,必须使用OUT来声明一下,他这里也确实需要,需要判断这个部门一个月额外付出多少成本,对每个人都加薪,额外输出多少钱,create or replace,procedure,加薪,add_sal,使用这个,add_sal加薪,需要在里面给定部门,dept_id,number类型的,逗号,他需要判断额外需要多少钱,这个作为一个out型的参数,他也是number类型的,没有return了,is,额外的要定义一个变量,一个部门有很多人,就定义一个cursor,cursor,让他去遍历一下,cursor sal_cursor is select,你到底需要查什么,employees,where department_id = dept_id,这都需要查什么,看你都需要什么,一般也是需要的,额外需要付出多少,一般employee_id也用,不对的话再改,employee_id,salary,然后再加上hire_date,我先取这三个变量,从这三个表当中,这是加薪,这是加的一个东西,多定义一个变量,一个是0.03,一个是0.01,比如我再定义一个变量,v_i吧,number类型的,两位小数,就是用来记录这个东西,差不多,然后直接begin,用for,省得你open,fetch,close,循环,然后呢,判断一下hire_date,不同的hire_date所赋的值是不一样的,如果c的hire_date是在这个时间段的,这个怎么写啊,让这个hire_date小于一个时间,字符串和date的一个转换,那我就这样一下吧,to_char,是一个date型的,如果这个是小于1995,按说字符串是不可以比大小的,但是如果你字符串是纯数字的话,他有一个隐式转换,隐式转换纯数字,纯数字的字符串可以隐式转换,如果是这样的话,then,为其加百分之五,v_i记录一下,加薪的幅度,elsif,1998,0.03,其余的else,直接then了,然后if就是end if,end if完了,还是得更新一下他的工资,下面操作,1更新工资,2付出的成本,先看这个,一开始他的成本在这儿呢,在这给他赋值,temp冒号等于0,付出的成本,temp = temp + c.salary*v_i,这就是额外多的,更新工资,update,update employees,set salary = salary(1+v_i),where employee_id = c.employee_id,然后给他这样操作了,操作完以后,end loop,endcreate or replace procedure add_sal(dept_id number,temp_sal out number)iscursor sal_cursor is select employee_id,salary,hire_date from employees where department_id = dept_id;v_i number(4,2) := 0;begintemp_sal := 0;for c in sal_cursor loopif to_char(c.hire_date,'yyyy') < '1995' then v_i := 0.05;elsif to_char(c.hire_date,'yyyy') < '1998' then v_i := 0.03;else v_i := 0.01;end if;update employees set salary = salary*(1+v_i) where employee_id = c.employee_id;temp_sal := temp_sal + c.salary*v_i;end loop;end;

创建好以后,然后呢,执行,这里你定义一个变量,declare定义一个变量,定义一下到底要花多少钱,number,10个单位,冒号等于0,begin,add_sal,80号部门的,然后呢v_temp,我把你要花的给你输出一下create or replace procedure add_sal(dept_id number,temp_sal out number)iscursor sal_cursor is select employee_id,salary,hire_date from employees where department_id = dept_id;v_i number(4,2) := 0;begintemp_sal := 0;for c in sal_cursor loopif to_char(c.hire_date,'yyyy') < '1995' then v_i := 0.05;elsif to_char(c.hire_date,'yyyy') < '1998' then v_i := 0.03;else v_i := 0.01;end if;update employees set salary = salary*(1+v_i) where employee_id = c.employee_id;temp sal := temp_sal + c.salary*v_i;end loop;dbms_output.put_line(temp_sal);end;

declarev_temp number(10) := 10;beginadd_sal(80,_v_temp);end;

这就叫存储过程,我觉得存储过程比存储函数要简单,你把存储函数理解理解,这个改一改就了事了,这就是存储过程,存储过程就搞定了

plsql(轻量版)-存储函数存储过程相关推荐

  1. plsql(轻量版)_记录类型2

    PL/SQL这一块,整个这一块需要大家掌握什么,就是他基本的格式,PL/SQL,基本的语法格式,如何声明一个变量,然后程序从哪里执行,执行的格式是什么,出现异常怎么处理,基本的语法格式,就这样写吧,第 ...

  2. plsql(轻量版)_基本语法

    ORACLE的组件也可以用PL/SQL去写,后边有存储过程,存储函数,触发器,可以自己来写存储过程,或者叫触发器,那前面有哪些我们就走一走,这里实际上是一本小书了,59页,比较经典版的plsql,我们 ...

  3. plsql轻量版存储过程和存储函数

  4. plsql(轻量版)_触发器

    触发器是许多关系型数据库系统都提供的一项技术,在ORACLE系统里,触发器类似过程和函数,都有声明,执行和异常处理过程的PL/SQL块,这是他创建的一个格式,这个触发器的作用是什么,触发器以独立的对象 ...

  5. plsql(轻量版)_游标的使用2

    游标你们记得,它是处理多行数据的,有点类似于集合里面的迭代器一样,一条条给你遍历打印一下,这个也是给他取出一条条的数据,就要使用到游标14. 利用游标, 调整公司中员工的工资: 工资范围 调整基数0 ...

  6. plsql(轻量版)_游标的使用1

    叫游标的使用,游标,以前没有听过这个名,什么是游标,他的作用是什么,如何来声明,怎么来使用,主要是你要掌握他是干嘛的,怎么用,游标,在PL/SQL程序当中,对于处理多行记录的事务,经常使用游标来实现, ...

  7. plsql(轻量版)_记录类型1

    定义变量,变量类型的,这个是可变的 这里涉及到一个概念叫记录类型,记录类型是把逻辑相关的数据作为一个单元存储起来,称作一个record,其作用是存储互不相同但逻辑相关的信息,这个叫记录类型,这个是以什 ...

  8. plsql(轻量版)_异常处理机制

    一个优秀的程序都应该能够正确的处理各种出错异常,并尽可能的从错误中恢复,ORACLE提供异常来实现错误处理,异常exception这个词还是这个,处理正常执行过程中未预料的事件,他分为预定义的错误,和 ...

  9. plsql(轻量版)_流程控制

    记录类型百分号type,使用它的优点,所引用的数据库列的数据类型不必知道,要不你就得知道它的类型和他的一样的,这里你可以实时改变,列的数据类型改变,我这里也跟着改,动态的来获取你的类型 这里还有个百分 ...

最新文章

  1. 用python写计算机专业_自学open cv,用Python写的,本人是一名学生党,因为我本专业不是搞计算机的_cc霜_学生党_教育_教育其他...
  2. Java 8系列之Stream的强大工具Collector
  3. 一步一步识别验证码(切分和识别)
  4. luov之windows 常用端口详解
  5. 解决E: 仓库 “http://ppa.launchpad.net/fcitx-team/nightly/ubuntu bionic Release” 没有 Release 文件。
  6. RTX5 | 线程管理05 - 线程挂起osThreadSuspend与线程恢复osThreadResume
  7. python apscheduler 动态_基于Flask-APScheduler实现添加动态定时任务
  8. UI网格,提升效率,爱上做设计
  9. karto探秘之open_karto 第五章 --- 栅格地图的生成
  10. 【西汉文学】之《贾谊·过秦论》
  11. plc控制伺服电机 四轴攻丝机案例 该程序为plc控制伺服电机的工程案例程序,包含伺服电机接线图,包含程序流程的详细解释说明
  12. Ubuntu开机加速
  13. YOLOv1的pytorch复现版本,博主亲自测试完整复现。
  14. 国产化服务器兼容系统,必须兼容中国芯,国产操作系统再迎来发展机遇?
  15. ZJCTF-Triple Language Write up
  16. Linux内核与编程
  17. 【高等数学】02 函数的特性,有界性,无界性,单调性,奇偶性,周期性,反函数,复合函数
  18. 「Activiti精品 悟纤出品」Activiti7数据库表 - 第332篇
  19. python有什么好玩的库_python有什么好玩的库
  20. 最新裂变营销推广系统+邀约链接/注册/卡密系统

热门文章

  1. 密钥登陆Linux服务器
  2. c# xml的增删改查操作 xmlDocument 的用法
  3. javascript实现kruskal算法
  4. C#生成PDF文件中时,设置边框为虚线和隐藏显示单个或者多个边框。
  5. 区块链行业级应用服务商识数信科获千万元天使轮融资...
  6. django学习(1)-----项目组成
  7. SSH框架之SSH前言
  8. web office apps 在线预览实践
  9. MyISAM 和InnoDB 的区别.(存储,索引, 事务, 锁)
  10. segue和delegate实现两个页面传值