目录

一、Oracle

1、概述

2、oracle的安装--服务器端

3、PLSQL客户端的安装--配置本地服务

3.1创建数据库

二、PLSQ客户端的使用

注意:常见错误

1、创建用户:文件–>新建–>用户

2、创建表

3、特殊的语法

3.1 日期

3.2 性别替换

3.3 分页查询

三、oracle独特的技术

1、 过气技术

2、虚表 dual

3、序列 sequence

3.1、创建序列

3.2、使用序列

4、视图 view

5、触发器 trigger

6、存储过程 procedure


一、Oracle

1、概述

oracle和MySQL一样,可以存储以及管理数据。

Oracle是收费的,MySQL是免费的。

2、oracle的安装--服务器端

一定要"以管理员身份运行",Oracle是系统级别的,要安装服务,要求权限大。一般安装时把防火墙关闭,否则很容易安装失败。

win7 把mysql移到其他盘 mysql数据库从c盘迁移到d盘_win7 把mysql移到其他盘

win7 把mysql移到其他盘 mysql数据库从c盘迁移到d盘_oracle_02

win7 把mysql移到其他盘 mysql数据库从c盘迁移到d盘_服务器_03

win7 把mysql移到其他盘 mysql数据库从c盘迁移到d盘_服务器_04

win7 把mysql移到其他盘 mysql数据库从c盘迁移到d盘_oracle_05

win7 把mysql移到其他盘 mysql数据库从c盘迁移到d盘_CRM_06

win7 把mysql移到其他盘 mysql数据库从c盘迁移到d盘_win7 把mysql移到其他盘_07

安装OracleXEUniv简版.exe,会自动创建EX服务。如果安装安装版本,需要手动创建本地服务。

安装完成后,侦听Listener和ServiceXE自动启动。

win7 把mysql移到其他盘 mysql数据库从c盘迁移到d盘_数据库_08

安装时,最好不要安装到c盘,选择d盘。安装时需要输入system的密码,这个一定要记住,oracle的密码是无法破解的。忘记了只能重新安装。切记。

注意:

1)默认oracle会开启8080网页服务,它跟tomcat默认8080端口冲突。可以关闭oracle的8080,或者换tomcat的默认端口。

2)oracle安装完成后,不能使用sql-plus测试是否安装成功,因为它权限非常大。可以直接和oracle通讯。可以使用plsql工具,如果可以连接,则写的程序才能正常访问。

3)如果安装失败,先停掉侦听服务,再停掉Service服务,然后运行安装包,进行卸载。

3、PLSQL客户端的安装--配置本地服务

访问远程Oracle服务端。
远程访问前,在服务器上安装Oracle服务器端,客户端安装Oracle客户端,使用PL/SQL通过Oracle客户端访问Oracle服务端。

win7 把mysql移到其他盘 mysql数据库从c盘迁移到d盘_win7 把mysql移到其他盘_09

修改tnsnames.ora文件配置远程访问的地址:

XEremote =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.105)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = XE)
    )
  )

3.1创建数据库

注意事项
racle的数据库概念和mysql不同,它是创建一个账号,将所有表等都放在这个账号下。所以在oracle中的账户等同于mysql中的数据库。
不要将system给用户直接使用,权限太大,造成安全隐患,数据泄露,甚至删除别人的账号(数据库)。切不可给非法分子留下删库跑路的机会。所以通常给每个业务单独创建账号,单独分配权限。
密码安全
System账号不能修改,它是超级管理员,密码必须安全,否则非常危险,那实际开发中企业怎么设置的呢?

14yHl9t-hjCMT 疑似银河落九天-回家吃馒头

二、PLSQ客户端的使用

MySQL:数据库—表----字段/记录
Oracle: 用户—表----字段/记录
登录PLSQL:使用system和安装的密码,名称:system 口令:123456

注意:常见错误

如果太久未访问oracle,oracle会自动关闭链接,如上午访问,中午一直未用,下午再执行SQL就报下面错误。关闭,重新打开即可。

win7 把mysql移到其他盘 mysql数据库从c盘迁移到d盘_CRM_10

1、创建用户:文件–>新建–>用户

win7 把mysql移到其他盘 mysql数据库从c盘迁移到d盘_数据库_11

win7 把mysql移到其他盘 mysql数据库从c盘迁移到d盘_win7 把mysql移到其他盘_12

2、创建表

win7 把mysql移到其他盘 mysql数据库从c盘迁移到d盘_数据库_13

win7 把mysql移到其他盘 mysql数据库从c盘迁移到d盘_CRM_14

win7 把mysql移到其他盘 mysql数据库从c盘迁移到d盘_oracle_15

win7 把mysql移到其他盘 mysql数据库从c盘迁移到d盘_数据库_16

win7 把mysql移到其他盘 mysql数据库从c盘迁移到d盘_oracle_17

3、特殊的语法

  1.  输入SQL语句执行,可以输入多条SQL,通过选中的内容进行执行,不选中执行所有。
  2. 从SQL:1999开始,标准简称中的短横线(-)被换成了冒号(:),而且标准制定的年份也改用四位数字了。前一个修改的原因是ISO标准习惯上采用冒号,ANSI标准则一直采用短横线。
  3. 标准是用来打破的,所以注意各数据库厂商虽然遵循了规范标准,但也自己实现了个性的内容,一些函数,存储过程等

3.1 日期

Oracle默认日期格式为:日-月-年。09-6月-99日期为1999年6月9日

select t.*  from stu t where sclass='java'
--日期类型,默认格式是 日-月-年
insert into stu values('rose',0,'1/7月/2021','java',3)
--改成习惯的年-月-日
alter session set nls_date_format='yyyy-mm-dd'
--遵循新规则插入新数据
insert into stu values('tom',0,'2021-7-1','java',4)

3.2 性别替换

方式1:decode()

decode(1,2,3,4,5)

1是字段名 ,2是判断条件,3要执行的内容, 4相当于2判断失败 ,5是要执行的内容

select t.*, decode(ssex,0,'男',1,'女')  from stu t

方式2:case...when...

select sname,ssex,
  case ssex when '0' then '女' else '男' end sex
from stu

3.3 分页查询

rownum关系运算分页查询,使用关系运算符(大于或小于)来取范围查询

而limit的分页查询是取几条,从哪取

select top 1 * from stu						--sqlServer数据库
select * from stu limit 1					--mysql数据库
select * from stu where rownum<2			--oracle数据库

三、oracle独特的技术

1、 过气技术

下面的技术在历史长河中已经被淘汰,但老项目,小项目依然再用,大家了解下即可。这些技术很多阿里的开发手册中已经禁止使用。

2、虚表 dual

dual是一个虚拟表,mysql没有,用来构成select的语法规则,oracle保证dual里面永远只有一条记录,用它可以做很多事情。

select 1 from dual							--虚拟出一个数字列
select 'abc' from dual					--虚拟出一个字符串列
#获取系统当前日期
select sysdate from dual
select now() from dual---mysql查询时间
select sys_guid() from dual				--获取uuid

3、序列 sequence

Oracle自身提供的自增主键支持,和MySQL里的主键+自增效果一样

但oracle可以自己设置自增的规则

3.1、创建序列

win7 把mysql移到其他盘 mysql数据库从c盘迁移到d盘_win7 把mysql移到其他盘_18

win7 把mysql移到其他盘 mysql数据库从c盘迁移到d盘_服务器_19

3.2、使用序列

--使用序列,自己指定开始位置和变化规则
select sid_seq.nextval from dual--查询下一次值
select sid_seq.currval from dual --查询当前的值

--给id赋值,序列会自动+1
insert into stu(sid) values(STU_ID_SEQ.nextval)--以后插入新数据时,sid都可以用序列的值

--删除指定范围的表记录
delete from stu where sid >160
select * from stu

4、视图 view

步骤:view-->新建-->给name列取个名字确定即可

--视图:
-- 好处:提高查询效率
-- 缺点:SQL无法优化
--第一步:创建视图 --把查询结果缓存到视图里
create or replace view StuView as
select * from stu where sname like '%o%'
--第二步:使用视图
select * from stu where sname like '%o%'--不需要每次都要先创建视图,再查询,因为上一步已经把结果缓存到视图当中另外,拿来使用即可
select * from stuview    --直接查视图

5、触发器 trigger

步骤:文件-->新建-->程序窗口-->触发器

win7 把mysql移到其他盘 mysql数据库从c盘迁移到d盘_win7 把mysql移到其他盘_20

记录生效点:BEFORE/AFTER
记录的操作:INSERT/UPDATE/DELETE

win7 把mysql移到其他盘 mysql数据库从c盘迁移到d盘_数据库_21

win7 把mysql移到其他盘 mysql数据库从c盘迁移到d盘_win7 把mysql移到其他盘_22

--设置触发器 ---禁用,因为无法控制程序员的权限,可能有安全隐患
create or replace trigger UPDATE_STU_TRI
  before update on stu  
  for each row
declare
  -- local variables here
begin
  --判断,如果满足了条件,就执行触发器的功能
  IF :NEW.SSEX>5 THEN  
       :NEW.SSEX := 1;--把新的值设置成1
  END IF;

end UPDATE_STU_TRI;

--使用触发器:
SELECT * FROM STU
update stu set ssex=10;--触发器执行,都是1了
update stu set ssex=3;--不满足触发器,就是3

6、存储过程 procedure

概念:

存储过程(Stored Procedure)其实就是数据库端的编程,在数据库为王的时代,虽然已经过去,当时数据库大集中,部署在超级好的服务器,甚至是小型机,所以执行的性能超群,运行在上面的程序自然也就性能极佳。但当分布式架构兴起后,数据库在整个架构中的作用一再衰落,逐步边缘化。再者存储过程中的SQL是依赖数据库厂商,每个厂商都有其个性的SQL,导致程序迁移数据库时,如从oracle迁移到mysql时基本重写,工作量巨大,造成修改的风险。于是主流方式已经将其从数据库端前置到java程序端实现,这样迁移数据库变得轻松。

案例:

大家浏览下就好,难不?这样的东西非常难维护和调试,这就是被禁止的原因。
 

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go

ALTER PROCEDURE  [dbo].[SP_TMS_AUTO_BILLING] (
@V_TMS_ORDER_ID              VARCHAR (32),              --订单主ID
@V_RETUREN_VALUE             VARCHAR (20)  output       --状态返回
				    )
AS
/***********************************************************************
**  Stored Procedure Documentation
**  Stored Procedure Name: SP_TMS_AUTO_BILLING
**  Creation Date: 2010-3-1
**  Author: 
**  Program ID:  
**  Input Parameters:

**  Output Parameters:

**  Return Status Values:
**  Usage:
**  Local Variables:
**  Called By:
**  Calls:
**  Data Modifications:
**  Updates:
************************************************************************/
BEGIN

	DECLARE @V_OPERATION_ITEM VARCHAR (30)     ----订单上的费用协议操作项目
	DECLARE @V_SERVICE_TYPE VARCHAR (50)        ----订单上的服务类型
	DECLARE @V_CUSTOMER_CONTRACT VARCHAR(30)   ----订单上的费用协议号
	DECLARE @V_SERVICE_LEVEL VARCHAR(30)       ----订单上的服务时限
	DECLARE @V_CHARGE_UNIT VARCHAR(20)         ----订单上的计件单位
	DECLARE @V_CARGO_TYPE VARCHAR(50)          ----订单上的货物类型
	DECLARE @V_ESTIMATED_CARGO_PACKAGES NUMERIC   ---订单上的货物件数
	DECLARE @V_ESTIMATED_CARGO_WEIGHT NUMERIC     ---订单上的货物重量
	DECLARE @V_ESTIMATED_CARGO_CUBE NUMERIC       ---订单上的货物体积
	DECLARE @V_BILLING_OFFICE VARCHAR(50)         ---订单上的结算公司
	DECLARE @V_HOME_CURRENCY VARCHAR(3)           ---结算公司本位币


	DECLARE @V_CHARGE_CODE VARCHAR(20)       ---客户计费协议费用项目中的费用代码
	DECLARE @V_CHARGE_ITEM_NAME VARCHAR(50)       ---客户计费协议费用项目中的费用名称
	DECLARE @V_RATES_NUMBER     VARCHAR(20)       ---客户计费协议费用项目中的费率号
	DECLARE @V_FRT_NAME_EN      VARCHAR(50)       ---费用英文名称

	DECLARE @V_CUST_OPERATION_ITEM_ID VARCHAR(50)    ----操作项的ID
	DECLARE @V_CUST_CONTRACT_ID VARCHAR(50)          ---计费协议ID
	DECLARE @V_CRM_CUST_ID VARCHAR(50)               ---客户ID

	DECLARE @V_CHARGE_QUANTITY NUMERIC               ----结算总量

	DECLARE @V_UNIT_PRICE NUMERIC                    ----费用单价
	DECLARE @V_CHARGE_CURRENCY VARCHAR(20)           ----费用币别
	DECLARE @V_CUST_CODE          VARCHAR(50)           ----客户代码
	DECLARE @V_EXCHANGE_RATE      NUMERIC            ----汇率

	DECLARE @V_CUST_INNER_OUTER   VARCHAR(50)        ----对内或者对外

	DECLARE @V_MIN_RATES NUMERIC                     ----计费协议里面的最低起运价
	DECLARE @V_AMOUNT NUMERIC                        ----费用表里面的amount

	---取去订单下需要的数据
	SELECT @V_SERVICE_TYPE = SERVICE_TYPE, @V_CUSTOMER_CONTRACT = CUSTOMER_CONTRACT, 
		   @V_SERVICE_LEVEL = SERVICE_LEVEL, @V_CHARGE_UNIT = CHARGE_UNIT,
		   @V_CARGO_TYPE = CARGO_TYPE, @V_ESTIMATED_CARGO_PACKAGES =ESTIMATED_CARGO_PACKAGES,
		   @V_ESTIMATED_CARGO_WEIGHT = ESTIMATED_CARGO_WEIGHT, @V_ESTIMATED_CARGO_CUBE = ESTIMATED_CARGO_CUBE,
		   @V_BILLING_OFFICE = BILLING_OFFICE, @V_HOME_CURRENCY = HOME_CURRENCY
	from TMS_ORDER
		LEFT JOIN SYS_OFFICE ON BILLING_OFFICE = OFFICE_CODE
	where TMS_ORDER_ID = @V_TMS_ORDER_ID

	---判断费用单位对应的结算总量
	IF(@V_CHARGE_UNIT = '件数')
		set @V_CHARGE_QUANTITY = @V_ESTIMATED_CARGO_PACKAGES
	ELSE IF(@V_CHARGE_UNIT = '体积')
		SET @V_CHARGE_QUANTITY = @V_ESTIMATED_CARGO_CUBE
	ELSE
		SET @V_CHARGE_QUANTITY = @V_ESTIMATED_CARGO_WEIGHT 


	----将符合的费用查找出来
	DECLARE
		V_CHARGE_CURSOR CURSOR FOR
		SELECT CRM.CHARGE_CODE, CRM.CHARGE_ITEM_NAME, SFD.FRT_NAME_EN, 
			   CRM.RATES_NUMBER, 
			   CUOI.CUST_OPERATION_ITEM_ID, CUOI.CUST_CONTRACT_ID,
			   CC.CUST_CODE, CCC.CRM_CUST_ID, CC.CUST_INNER_OUTER
		FROM CRM_CUST_CHARGE_ITEM CRM 
		LEFT JOIN CRM_CUST_OPERATION_ITEM CUOI ON CRM.CUST_OPERATION_ITEM_ID = CUOI.CUST_OPERATION_ITEM_ID
		LEFT JOIN CRM_CUST_CONTRACT CCC ON CUOI.CUST_CONTRACT_ID = CCC.CUST_CONTRACT_ID
		LEFT JOIN CRM_CUST CC ON CC.CRM_CUST_ID = CCC.CRM_CUST_ID
		LEFT JOIN SB_FRT_DEF SFD ON SFD.FRT_CODE = CRM.CHARGE_CODE
		LEFT JOIN TMS_OPERATION_ITEM TOI ON CUOI.OPERATION_ITEM=TOI.OPERATION_ITEM
		WHERE CCC.CONTRACT_NUMBER = @V_CUSTOMER_CONTRACT
		AND CUOI.SERVICE_TYPE = @V_SERVICE_TYPE
		AND CUOI.SERVICE_PERIOD = @V_SERVICE_LEVEL
		AND CUOI.CARGO_TYPE = @V_CARGO_TYPE
		AND TOI.TMS_ORDER_ID = @V_TMS_ORDER_ID
		/**
		AND EXISTS (SELECT 1 FROM TMS_OPERATION_ITEM TOI 
						WHERE CUOI.OPERATION_ITEM = TOI.OPERATION_ITEM 
						AND TMS_ORDER_ID = @V_TMS_ORDER_ID
					)
		**/

	OPEN V_CHARGE_CURSOR

	FETCH NEXT FROM V_CHARGE_CURSOR 
			INTO @V_CHARGE_CODE, @V_CHARGE_ITEM_NAME, @V_FRT_NAME_EN, @V_RATES_NUMBER, 
				 @V_CUST_OPERATION_ITEM_ID, @V_CUST_CONTRACT_ID, @V_CUST_CODE, @V_CRM_CUST_ID,
				 @V_CUST_INNER_OUTER
	IF(@@FETCH_STATUS!=0)
		set @V_RETUREN_VALUE = '没有匹配操作项'
	WHILE(@@FETCH_STATUS = 0)
		BEGIN

			set @V_RETUREN_VALUE = '自动计费完成'
			---取出费率表中符合条件的记录
			SELECT @V_UNIT_PRICE = UNIT_PRICE, @V_CHARGE_CURRENCY = CHARGE_CURRENCY, @V_MIN_RATES = MIN_RATES
			FROM CRM_CUST_CHARGE_RATE
			WHERE CHARGE_UNIT = @V_CHARGE_UNIT
			AND CUST_CONTRACT_ID = @V_CUST_CONTRACT_ID
			AND RATES_NUMBER = @V_RATES_NUMBER
			AND CHARGE_UNIT_FROM < @V_CHARGE_QUANTITY
			AND CHARGE_UNIT_TO >= @V_CHARGE_QUANTITY

			---看是否有对应的协议汇率维护
			IF(@V_UNIT_PRICE IS NULL)
				PRINT 'NO DATA'
			ELSE
				BEGIN
				----查询汇率
				SELECT @V_EXCHANGE_RATE = EXCHANGE_RATE
					from CRM_CUST_EXCHANGERATE
				WHERE CRM_CUST_ID = @V_CRM_CUST_ID
				AND LOCAL_CURRENCY_CODE = @V_HOME_CURRENCY
				AND FOREIGN_CURRENCY_CODE = @V_CHARGE_CURRENCY

				---如果不存在取系统中的汇率
				IF(@V_EXCHANGE_RATE IS NULL)
					BEGIN
						IF(@V_CUST_INNER_OUTER = 'INTERIOR')   ----判断是对内的还是对外的汇率
							SELECT @V_EXCHANGE_RATE = RATE_IN
							FROM SB_RATE
							WHERE STANDARD_CUR_CODE = @V_HOME_CURRENCY
							AND ORIGINAL_CUR_CODE = @V_CHARGE_CURRENCY
						ELSE
							SELECT @V_EXCHANGE_RATE = RATE
							FROM SB_RATE
							WHERE STANDARD_CUR_CODE = @V_HOME_CURRENCY
							AND ORIGINAL_CUR_CODE = @V_CHARGE_CURRENCY
					END

				IF(@V_EXCHANGE_RATE IS NULL)
					BEGIN
						PRINT @V_HOME_CURRENCY
						print @V_CHARGE_CURRENCY
						PRINT 'SYS NOT EXCHANGE RATE'
						RETURN 1
					END

				print @V_EXCHANGE_RATE

				----判断费用amount是否比最低起运价低,如果低,就取最低起运价,否则却当前值
				SET @V_AMOUNT = @V_UNIT_PRICE*@V_CHARGE_QUANTITY
				IF(@V_AMOUNT IS NOT NULL AND @V_MIN_RATES IS NOT NULL)
					BEGIN
						IF(@V_AMOUNT<@V_MIN_RATES)
							SET @V_AMOUNT = @V_MIN_RATES
					END						

				----插入费用表
				INSERT INTO TMS_FREIGHT(TMS_FREIGHT_ID,
										TMS_ORDER_ID,
										FRT_CODE,
										FRT_NAME,
										FRT_NAME_CN,

										RP_IND,
										UNIT_PRICE,
										CHARGE_QUANTITY,
										CHARGE_UNIT,
										BILLING_STATION,

										CUST_CODE,
										CURRENCY,
										EXCHANGE_RATE,
										AMOUNT,
										LOCAL_CURRENCY,

										LOCAL_CURRENCY_AMOUNT,
										IS_SHARE,
										NEED_SHARE,
										IS_AUTO,
										IS_SETTLE,

										IS_REVICED,
										RECORD_VERSION

										)
				SELECT	NEWID(),
						@V_TMS_ORDER_ID,
						@V_CHARGE_CODE,
						@V_FRT_NAME_EN,
						@V_CHARGE_ITEM_NAME,

						'0',
						@V_UNIT_PRICE,
						@V_CHARGE_QUANTITY,
						@V_CHARGE_UNIT,
						@V_BILLING_OFFICE,

						@V_CUST_CODE,	
						@V_CHARGE_CURRENCY,
						@V_EXCHANGE_RATE,
						@V_AMOUNT,
						@V_HOME_CURRENCY,

						@V_AMOUNT*@V_EXCHANGE_RATE,
						0,
						0,
						1,
						0,

						0,		
						1
			END
			-----插入表结束		


			FETCH NEXT FROM V_CHARGE_CURSOR 
			INTO @V_CHARGE_CODE, @V_CHARGE_ITEM_NAME, @V_FRT_NAME_EN, @V_RATES_NUMBER, 
				 @V_CUST_OPERATION_ITEM_ID, @V_CUST_CONTRACT_ID, @V_CUST_CODE, @V_CRM_CUST_ID,
				 @V_CUST_INNER_OUTER
		END
		CLOSE V_CHARGE_CURSOR
		DEALLOCATE V_CHARGE_CURSOR

END