sqlserver 随机取数据 order by newid()此函数
oracle 建表或建过程时提示,用户不存在,可能1:方案或空间重新选择一下
vs
=============================还原数据库======================
1:新建数据库:a
2:数据库->右键->任务->还原数据库,选择:还原数据库为:a
3:从设备选择路径后,回到此窗口,选项:(1)强制还原,(2)物理路径改为sql server的安装路径如:e:/MSSQL/Data/a_Data
Log:e:/MSSQL/Data/a_Log
此问题解决:5小时2009.11.29
=======================理论==============================
use Student
go
delete * from st where sAge=40
go
*代表的是列(即字段) :不是值,是字段,不是行
delete truncate table tableName
delete truncate 删除的是表中值,不是表名
删除表名:drop table tableName
use Student
go
select * from stu *:查询所有字段 select * from
stu //*字段
select from
stu //字段中的值
go
use Student
go
select from stu 查询所有字段中的值
go
select top 2 computer_mark as
'computerScore',idse=student_id from student_mark
order by idse desc
=赋值运算符
t_sql 用鼠标拖动选中一句,执行时只执行引句
drop:删除表,或库
remove:移除文件
delete:删除表中值 一般只在删除值时用delete 其他表或
字段等用drop
=======================db常识==============================
新闻类型表结构:cd_dbNewType cd_//字典表,一般为类型表,只有id,name,要与别的表建立关系才有意义加cd_区别为字典表
sql学习宝网上搜下,sql学习的
======================约束===============================
唯一约束:约束的是一列,即此列中的每一行在表中唯一,不能有两行中的值相同,一个表中可约束多个列,且列值可为空
标识列,值自增,类型只能为整形有decimal、int、smallint、numeric
修改表时添加强制约束
alter talbe book
add constraint PK_stuno primary key(stuno)--主健约束
add constraint UQ_stuid unique(stuid)--唯一约束,约束此字段中不能有两行值重复
add constraint DF_address default('地址不详') for address--默认约束
add constraint CK_stuage check(stuage between 15 and 40)也可这样写(stuage>=15 and stuage<=40)--检查约束[约束范围]
add constraint FK_stuno foreign key (stuno) references stuinfo(stuno)---stuinfo主键表
删除约束
alter table stuinfo
drop constraint DF_address
========================增删改查=============================
------------------------------------增修
表中的数据复制到另一个表中
insert into book2(stuno,bookname,booknum)select stuno,bookname,booknum from book//select
book表中的字段中的值复制到book2表中字段下
插入
insert into book(stuno,bookname, booknum)values('stu001','.net开发',1,getdate())或
---insert into book values('stu001','.net开发',1)//插入全部,主键是自增列的话主键除外
go
更新
update book set booknum=booknum*10 where bookid=2
表复制
select * into table2 from table1
select id,name,area into table2 from table1
------------------------------------删
删除一条记录
delete from book where bookid=3
删除表中值
truncate table book--删除表中值,字段存在
------------------------------------查
在查询中使用常量和运算符
SELECT student_name +':'+ student_name+ '->' + student_name
FROM student_inf
注:select后的列与加入符号的数据类型必须匹配。
排序
select english from score order by english,yuwen asc--升序 desc--降序
查询
select top 2 * from score
限制返回数据行
select top 2 id,name from score
限制返回行百分比
select top 80% id,name from score
select id as '学号' ,name '姓名','地区'=area from score where id=3
不重复的记录
select distinct name from product
多个条件查询
select name,price from product where type='日用品' or type='饮料'也可这样写
select name,price from product wrhere type in('日用品','饮料')
分组
select count(name),name from product group by name--分组
having分组条件
select name,sum(price) from product group by name having sum(price)<500--分组条件having子句:用于设置group by子句的条件
select * from stuinfo,book两表
IS NULL运算符:IS NULL
返回为空值的内容项
select id,age from stuinfo where name is null//is null is not null
联合查询
select books.BookName from books INNER JOIN --left join right join full join cross join
dbo.BookType ON dbo.Books.BookTypeId = dbo.BookType.BookTypeId where 1=1 and dbo.books.BookName like '%孔羸%' and 1=1也可这样写
select b.BookName from books b INNER JOIN--left join right join full join cross join
dbo.BookType t ON b.BookTypeId =t.BookTypeId where 1=1 and b.BookName like '%孔羸%' and 1=1
子查询
select stuno,stuname from stuinfo where stuno=(select stuno from book where bookname='.net' )
判断存不存在
select stuname from stuinfo where not exists(select bookcity from book where stuinfo.stuno=book.stuno and bookcity='济南')--exists存在 not exists不存在
联合查询
select tid,tname from t
union
select sid,sname from s
create talbe student_mark
(
id int IDENTITY(1,1) not null primary key,
name varchar(10) not null unique,
id int not null foreign key references student_info(student_id),
math_mark nvarchar(15) null default 'unknow',
student_age int not null check(student_age>15 and student_age<100)
)
============================函数=========================
---------------------------常用函数
日期函数
DateTime.Now.ToShortDateString();//2009-11-5
string s = DateTime.Now.ToShortTimeString();//13:29
select right('2009-11-513:29',5)//13:29
例子:一条新闻数据库中数据只显示时间
数据库中字段:date [varchar]类型,不用datetime类型,
插入数据时
string issuanceDate = DateTime.Now.ToShortDateString();//2009-11-5
issuanceDate += "" + DateTime.Now.ToShortTimeString();13:29发布时间
取数据时取后5位
.cs中
this.DataList1.DataSource = Db.Query("select top 5 header,right(issuanceDate,5) as a from dbNewInfo").Tables[0];
htm中
<asp:Label ID="Label2" runat="server" Text='<%# Eval("a") %>'></asp:Label>//绑定别名a
函数
select avg(english) from score where area='济宁'
AVG函数:返回组中值的平均值。
COUNT函数:返回组中 项目的数量。
SUM函数:返回表达式中所有 值的和。
MAX函数:返回表达式的最大值。
MIN函数:返回表达式的最小值。
日期函数
--GETDATE()返回当前时间
select GETDATE()
--DATEADD(日期类型参数,时间数,起始时间)
--在指定的日期上加上一段时间,返回新值
SELECT DATEADD(YYYY,2,'2008-8-8')
--DATEDIFF(日期类型参数,起始时间,结束时间)
--返回两个日期的间隔
SELECT DATEDIFF(YYYY,'2005-8-8','2008-8-8')
--YEAR()返回日期中的年部分
--MONTH()返回日期中的月份部分
--DAY()返回日期中的天数部分
SELECT YEAR(GETDATE())
--DATENAME(日期类型参数,日期)
--DATEPART(日期类型参数,日期)
--返回某个日期中的指定部分
SELECT DATEPART(mm,GETDATE())//11
SELECT DATEPART(y,'2009-1-1')//1
设置 描述
yyyy 年
q 季
m 月
d 日
w 一周中的第几天 星期几
ww 周 地几周
y 一年中的日数 一年中的第几天
h 时
n 分钟
s 秒
数学函数
--CEILING()返回大于或等于所给数字的最小整数
SELECT CEILING(3.2)
--FLOOR()返回小于或等于所给数字的最大整数
SELECT FLOOR(3.2)
--RAND()返回0-1之间的随机小数
SELECT RAND()
--ROUND()返回四舍五入值
SELECT ROUND(3.4545,3)
--ABS()返回绝对值
SELECT ABS(-8)
类型转换函数
--CAST(表达式,类型说明)函数
SELECT CAST(123.45 as nchar(10))
--CONVERT(类型说明,表达式) SELECT CONVERT(nchar(10),123.44)
------------------------------------------sql常用字符串函数
一、字符转换函数
1、ASCII()
返回字符表达式最左端字符的ASCII 码值。在ASCII()函数中,纯数字的字符串可不用''括起来,但含其它字符的字符串必须用''括起来使用,否则会出错。
2、CHAR()
将ASCII 码转换为字符。如果没有输入0 ~ 255 之间的ASCII 码值,CHAR() 返回NULL 。
3、LOWER()和UPPER()
LOWER()将字符串全部转为小写;UPPER()将字符串全部转为大写。
4、STR()
把数值型数据转换为字符型数据。
STR (<float_expression>[,length[, <decimal>]])
length 指定返回的字符串的长度,decimal 指定返回的小数位数。如果没有指定长度,缺省的length 值为10, decimal 缺省值为0。
当length 或者decimal 为负值时,返回NULL;
当length 小于小数点左边(包括符号位)的位数时,返回length 个*;
先服从length ,再取decimal ;
当返回的字符串位数小于length ,左边补足空格。
二、去空格函数
1、LTRIM() 把字符串头部的空格去掉。
2、RTRIM() 把字符串尾部的空格去掉。
三、取子串函数
1、left()
LEFT (<character_expression>, <integer_expression>)
返回character_expression 左起 integer_expression 个字符。
2、RIGHT()
RIGHT (<character_expression>, <integer_expression>)
返回character_expression 右起 integer_expression 个字符。
3、SUBSTRING()
SUBSTRING (<expression>, <starting_ position>, length)
返回从字符串左边第starting_ position 个字符起length个字符的部分。
四、字符串比较函数
1、CHARINDEX()
返回字符串中某个指定的子串出现的开始位置。
CHARINDEX (<'substring_expression'>, <expression>)
其中substring _expression 是所要查找的字符表达式,expression 可为字符串也可为列名表达式。如果没有发现子串,则返回0 值。
此函数不能用于TEXT 和IMAGE 数据类型。
2、PATINDEX()
返回字符串中某个指定的子串出现的开始位置。
PATINDEX (<'%substring _expression%'>, <column_ name>)其中子串表达式前后必须有百分号"%"否则返回值为0。
与CHARINDEX 函数不同的是,PATINDEX函数的子串中可以使用通配符,且此函数可用于CHAR、 VARCHAR 和TEXT 数据类型。
五、字符串操作函数
1、QUOTENAME()
返回被特定字符括起来的字符串。
QUOTENAME (<'character_expression'>[, quote_ character]) 其中quote_ character 标明括字符串所用的字符,缺省值为"[]"。
2、REPLICATE()
返回一个重复character_expression 指定次数的字符串。
REPLICATE (character_expression integer_expression) 如果integer_expression 值为负值,则返回NULL 。
3、REVERSE()
将指定的字符串的字符排列顺序颠倒。
REVERSE (<character_expression>) 其中character_expression 可以是字符串、常数或一个列的值。
4、REPLACE()
返回被替换了指定子串的字符串。
REPLACE (<string_expression1>, <string_expression2>, <string_expression3>) 用string_expression3 替换在string_expression1 中的子串string_expression2。
4、SPACE()
返回一个有指定长度的空白字符串。
SPACE (<integer_expression>) 如果integer_expression 值为负值,则返回NULL 。
5、STUFF()
用另一子串替换字符串指定位置、长度的子串。
STUFF (<character_expression1>, <start_ position>, <length>,<character_expression2>)
如果起始位置为负或长度值为负,或者起始位置大于character_expression1 的长度,则返回NULL 值。
如果length 长度大于character_expression1 中 start_ position 以右的长度,则character_expression1 只保留首字符。
六、数据类型转换函数
1、CAST()
CAST (<expression> AS <data_ type>[ length ])
2、CONVERT()
CONVERT (<data_ type>[ length ], <expression> [, style])
1)data_type为SQL Server系统定义的数据类型,用户自定义的数据类型不能在此使用。
2)length用于指定数据的长度,缺省值为30。
3)把CHAR或VARCHAR类型转换为诸如INT或SAMLLINT这样的INTEGER类型、结果必须是带正号或负号的数值。
4)TEXT类型到CHAR或VARCHAR类型转换最多为8000个字符,即CHAR或VARCHAR数据类型是最大长度。
5)IMAGE类型存储的数据转换到BINARY或VARBINARY类型,最多为8000个字符。
6)把整数值转换为MONEY或SMALLMONEY类型,按定义的国家的货币单位来处理,如人民币、美元、英镑等。
7)BIT类型的转换把非零值转换为1,并仍以BIT类型存储。
8)试图转换到不同长度的数据类型,会截短转换值并在转换值后显示"+",以标识发生了这种截断。
9)用CONVERT() 函数的style 选项能以不同的格式显示日期和时间。style 是将DATATIME 和SMALLDATETIME 数据转换为字符串时所选用的由SQL Server 系统提供的转换样式编号,不同的样式编号有不同的输出格式。
七、日期函数
1、day(date_expression)
返回date_expression中的日期值
2、month(date_expression)
返回date_expression中的月份值
3、year(date_expression)
返回date_expression中的年份值
4、DATEADD()
DATEADD (<datepart>, <number>, <date>)
返回指定日期date 加上指定的额外日期间隔number 产生的新日期。
5、DATEDIFF()
DATEDIFF (<datepart>, <date1>, <date2>)
返回两个指定日期在datepart 方面的不同之处,即date2 超过date1的差距值,其结果值是一个带有正负号的整数值。
6、DATENAME()
DATENAME (<datepart>, <date>)
以字符串的形式返回日期的指定部分此部分。由datepart 来指定。
7、DATEPART()
DATEPART (<datepart>, <date>)
以整数值的形式返回日期的指定部分。此部分由datepart 来指定。
DATEPART (dd, date) 等同于DAY (date)
DATEPART (mm, date) 等同于MONTH (date)
DATEPART (yy, date) 等同于YEAR (date)
8、GETDATE()
以DATETIME 的缺省格式返回系统当前的日期和时间
=========================数据库文件操作============================
创建数据库
数据库文件包括如下一些文件:
· 一个主数据文件(.mdf)
· 0个或多个辅助数据文件(.ndf)
· 1个或多个日志文件(.ldf)
create database stuDB
on primary--默认就属于primary主文件组,可省略
(
name='stuDB_data',--主数据文件的逻辑名,物理名的别名,数据库中的库名
filename='h:/databasefile/stuDB_data.mdf',--物理名,磁盘文件夹中的文件名,一个数据库有且只有个mdf
size=5mb,--主数据文件初始大小 主数据文件的默认大小为master数据库主数据文件的大小。
maxsize=100mb,--在数据库创建后,数据文件会逐步增大,但是能增长到的最大容量就是这个值所定义的。如果最大容量没有指定,则文件一直会填满整个磁盘。
filegrowth=15%--主数据文件的增长率
)
log on
(
name='stuDB_log',
filename='h:/databasefile/stuDB_log.ldf',
size=2mb,--日志文件在数据库文件中是必备的,至少有一个。在用最简单的create database命令创建数据库时,日志文件的默认大小为1MB。
--日志数据文件的默认大小为所有数据文件和的25%。
filegrowth=1mb--如果增量没有指定,则数据文件的默认增量为1MB,日志文件的默认增量为10%
拒绝语句
DENY CREATE TABLE TO aa
--拒绝aa用户 创建表 的权限
DENY CREATE TABLE,SELECT,INSERT,UPDATE TO aa,bb
--拒绝aa和bb用户 创建表,查询,插入,更新 的权限
DENY SELECT,INSERT,UPDATE ON jobs TO aa,bb
--拒绝aa和bb用户 拥有 查询,插入,更新表jobs 的权限
同意权限语句
GRANT CREATE TABLE TO aa
--授予aa用户 创建表 的权限
GRANT CREATE TABLE,SELECT,INSERT,UPDATE TO aa,bb
--授予aa和bb用户 创建表,查询,插入,更新 的权限
GRANT SELECT,INSERT,UPDATE ON jobs TO aa,bb
--授予aa和bb用户 拥有 查询,插入,更新表jobs 的权限
--备份数据库
BACKUP DATABASE pubs TO DISK='c:/pubs_sqldb_080926.bak'
--还原数据库
RESTORE DATABASE pubs FROM DISK='c:/pubs_sqldb_080926.bak'
删除数据库
DROP DATABASE db1,db2
--删除 数据库 数据库名
删除表
drop table tableName
drop:删除表,或库
remove:移除文件
delete:删除表中值 一般只在删除值时用delete 其他表或字段等用drop
alter table a
--add ss char(10)--添加一字段,即一列
--alter column ss char(20)--修改字段类型
drop column ss--删除一字段
drop table a,b--删除表
修改数据库
ALTER DATABASE dbdb
--修改 数据库 数据库名
ADD FILE
--添加 数据文件
(
NAME=test1dat2,
FILENAME='d:/sqlserver/data/testdat2.ndf',
SIZE=5
)
/*
注意:
主数据文件*.mdf,辅数据文件*.ndf
FILENAME中,数据文件存放的目录必须是已经存在的。
数据文件存放的路径中,尽量不要包括空格,·#¥@#$。、/等特殊符号。
*/
ADD LOG FILE
--添加 日志 文件
(NAME=testlog1,
FILENAME='d:/sqlserver/data/testlog1.ldf',
SIZE=5
)
MODIFY FILE
--修改 文件
(NAME=test1dat2,
SIZE=6
)
REMOVE FILE test1dat2
--移除 文件 逻辑文件名(NAME定义的)
)
新闻类型表结构:cd_dbNewType cd_//字典表,一般为类型表,只有id,name,要与别的表建立关系才有意义加cd_区别为字典表
==========================inner join===========================
INNER JOIN语法联接多个表建记录集
多表联接建立记录集是十分有用的,因为某些情况下,我们需要把数字数据类型显示为相应的文本名称,这就遇到了多表联接建立记录集的问题。比如作一个会员注册系统,共有五个表,会员信息数据表member、会员身份表MemberIdentity、会员权限表MemberLevel、会员类别表MemberSort和会员婚姻状况表Wedlock。如果想把会员注册信息全部显示出来,肯定要将这四个表连起来,否则大家看到的某些会员信息可能只是数据编号。
以会员类别表来说,在其数据表中,1代表普通会员,2代表高级会员,3代表终身会员,在显示时,如果不将会员类别表与会员详细数据表相关联,那么假如我们现在看到的是一名普通会员的注册信息,我们只能看到其类别为1,而谁又会知道1代表的是普通会员呢?所以要将会员类别表与会员详细数据表相关联,关联后,1就显示为普通会员,2就显示为高级会员,3就显示为终身会员,这样多好?同理,其它两个表也要与会员详细数据表相关联才能把数据编号显示为相应的名称。
前天制作网站后台时遇到此问题,在面包论坛、狂迷俱乐部、蓝色理想、和5D多媒体论坛发了贴子求救,都没有获得答案,只好自己研究,花了两天时间终于成功,现将其写成教程供大家分享,希望大家少走弯路。
本教程是把五个表联在一起,如果愿意,您可以将更多的表联在一起,方法大同小异啦~
步骤一:用Access软件建立一个名为Member的数据库,在其中建五个表,分别为:会员信息数据表member、会员身份表MemberIdentity、会员权限表MemberLevel、会员类别表MemberSort和会员婚姻状况表Wedlock。
●会员信息数据表member:
MemberID:自动编号,主键(ID号)
MemberSort:数字(会员类别)
MemberName:文本,会员姓名
Password:文本(会员密码)
MemberLevel:数字(会员权限)
MemberIdentity:数字(会员身份)
Wedlock:数字(婚姻状况)
MemberQQ:文本(QQ号码)
MemberEmail:文本(会员邮箱)
MemberDate:日期/时间(会员注册日期)
●会员身份表MemberIdentity:
MemberIdentity:自动编号,主键(ID号)
IdentityName:文本(会员身份名称)
●会员权限表MemberLevel:
MemberLevel:自动编号,主键(ID号)
LevelName:文本(会员权限名称)
●会员类别表MemberSort:
MemberSort:自动编号,主键(ID号)
SortName:文本(会员类别名称)
●会员婚姻状况表Wedlock
Wedlock:自动编号,主键(ID号)
WedlockName:文本(会员婚姻状况类别)
说明:五个表建好后,您可以自行设置您想要的类别,如会员权限,您可以设置两个类别--"未付费会员"和"已付费会员",编号分别为"1"、"2",如您设置了三个选项,那么第三个选项的编号当然就是"3"了。
下面我们所要作的工作就是把"1"、"2"之类的编号显示为"未付费会员"和"已付费会员",否则,大家谁会知道"1"代表的是"未付费会员","2"代表的是"已付费会员"?
步骤二:建DSN数据源,建记录集
●运行Dreamweaver MX软件,在会员注册信息显示页面建一个名为ConnMember(您也可以起其它的名称)的DSN数据源。
●点击服务器行为面板中的"绑定",建一个名为MemberShow的数据集,"连接"选择ConnMember,"表格"选择Member,"列"全选,"排序"选择MemberDate,降序。点击"高级"按钮,修改SQL框中自动生成的代码:
原代码为:
Select *
FROM Member
orDER BY MemberDate DESC
将代码修改为:
Select *
FROM (((Member INNER JOIN MemberSort ON Member.MemberSort=MemberSort.MemberSort) INNER
JOIN MemberLevel ON Member.MemberLevel=MemberLevel.MemberLevel) INNER JOIN MemberIdentity ON
Member.MemberIdentity=MemberIdentity.MemberIdentity) INNER JOIN Wedlock ON Member.Wedlock=Wedlock.Wedlock
orDER BY MemberDate DESC
修改完代码后,点击"确定",大功告成!
现在,您可以打开记录集看一下,五个表中的字段全部集成在MemberShow记录集中,您只要将相应的字段绑定在该字段想显示的单元格中即可。这下好了,所有的数字编号全部变成了相应的名称,如会员权限,不再是"1"和"2"的数字形式了,而是变成了相应的名称"未付费会员"和"已付费会员"。其它的数字编号也变成了显示的文本名称,是不是很开心呢?
注意事项:
●在输入字母过程中,一定要用英文半角标点符号,单词之间留一半角空格;
●在建立数据表时,如果一个表与多个表联接,那么这一个表中的字段必须是"数字"数据类型,而多个表中的相同字段必须是主键,而且是"自动编号"数据类型。否则,很难联接成功。
●代码嵌套快速方法:如,想连接五个表,则只要在连接四个表的代码上加一个前后括号(前括号加在FROM的后面,后括号加在代码的末尾即可),然后在后括号后面继续添加"INNER JOIN 表名X ON 表1.字段号=表X.字段号"代码即可,这样就可以无限联接数据表了:)
语法格式:
其实 INNER JOIN ……ON的语法格式可以概括为:
FROM (((表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号) INNER JOIN 表3 ON 表1.字段号=表3.字段号) INNER JOIN 表4 ON Member.字段号=表4.字段号) INNER JOIN 表X ON Member.字段号=表X.字段号
您只要套用该格式就可以了。
现成格式范例:
虽然我说得已经比较明白了,但为照顾初学者,我还是以本会员注册系统为例,提供一些现成的语法格式范例,大家只要修改其中的数据表名称和字段名称即可。
连接两个数据表的用法:
FROM Member INNER JOIN MemberSort ON Member.MemberSort=MemberSort.MemberSort
语法格式可以概括为:
FROM 表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号
连接三个数据表的用法:
FROM (Member INNER JOIN MemberSort ON Member.MemberSort=MemberSort.MemberSort) INNER
JOIN MemberLevel ON Member.MemberLevel=MemberLevel.MemberLevel
语法格式可以概括为:
FROM (表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号) INNER JOIN 表3 ON 表1.字段号=表3.字段号
连接四个数据表的用法:
FROM ((Member INNER JOIN MemberSort ON Member.MemberSort=MemberSort.MemberSort) INNER
JOIN MemberLevel ON Member.MemberLevel=MemberLevel.MemberLevel)
INNER JOIN MemberIdentity ON Member.MemberIdentity=MemberIdentity.MemberIdentity
语法格式可以概括为:
FROM ((表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号) INNER JOIN 表3 ON 表1.字段号=表3.字段号) INNER JOIN 表4 ON Member.字段号=表4.字段号
连接五个数据表的用法:
FROM (((Member INNER JOIN MemberSort ON Member.MemberSort=MemberSort.MemberSort)
INNER JOIN MemberLevel ON Member.MemberLevel=MemberLevel.MemberLevel) INNER
JOIN MemberIdentity ON Member.MemberIdentity=MemberIdentity.MemberIdentity)
INNER JOIN Wedlock ON Member.Wedlock=Wedlock.Wedlock
语法格式可以概括为:
FROM (((表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号) INNER JOIN 表3 ON 表1.字段号=表3.字段号) INNER JOIN 表4 ON Member.字段号=表4.字段号) INNER JOIN 表5 ON Member.字段号=表5.字段号
连接六个数据表的用法:略,与上述联接方法类似,大家举一反三吧:)
=====================================================
=====================================================
=====================================================
=====================================================
=====================================================
=====================================================
=====================================================
=====================================================
=====================================================
=====================================================
=====================================================
=====================================================
=====================================================
=====================================================
=====================================================
=====================================================
=====================================================