数据库——常用SQL语句总结

数据库是个好东西,最好是系统地学习一下相关的知识,当然,如果实在没有时间,那就学习一下如何操作数据库好了。这里就根据网上的各类总结文章,总结一下常用的SQL语句,给学习SQL的胖友,更是给健忘的自己。

一、基础操作

1、使用sql对数据库操作

  • 连接数据库命令: mysql -u root -p密码
  • 创建数据库:create database dbname;
  • 查看所有的数据库:show databases;
  • 删除数据库: drop database dbname;
  • 切换数据库:use dbname;

2.查看表结构:

  • desc tablename;

3、备份sql server
--- 创建 备份数据的 device

USE master
EXEC sp_addumpdevice 'disk', 'testBack', 'c:\mssql7backup\MyNwind_1.dat'

--- 开始 备份

BACKUP DATABASE pubs TO testBack 

4、创建新表

  • create table tabname(col1 type1 [not null] [primary key],col2 type2 [not null],..)

根据已有的表创建新表: 

  • A:create table tab_new like tab_old (使用旧表创建新表)
  • B:create table tab_new as select col1,col2… from tab_old definition only

5、删除新表

  • drop table tabname 

6、增加一个列

  • Alter table tabname add column col type

注:列增加后将不能删除。DB2中列加上后数据类型也不能改变,唯一能改变的是增加varchar类型的长度。


7、主键的添加与删除

  • 添加主键:Alter table tabname add primary key(col)
  • 删除主键: Alter table tabname drop primary key(col) 

8、索引的创建与删除

  • 创建索引:create [unique] index idxname on tabname(col….) 
  • 删除索引:drop index idxname

注:索引是不可更改的,想更改必须删除重新建。
9、视图的创建与删除

  • 创建视图:create view viewname as select statement 
  • 删除视图:drop view viewname

10、其他几个简单的基本的sql语句

  • 选择:select * from table1 where 范围
  • 插入:insert into table1(field1,field2) values(value1,value2)
  • 删除:delete from table1 where 范围
  • 更新:update table1 set field1=value1 where 范围
  • 查找:select * from table1 where field1 like ’%value1%’ ---like的语法很精妙,查资料!
  • 排序:select * from table1 order by field1,field2 [desc]
  • 总数:select count as totalcount from table1
  • 求和:select sum(field1) as sumvalue from table1
  • 平均:select avg(field1) as avgvalue from table1
  • 最大:select max(field1) as maxvalue from table1
  • 最小:select min(field1) as minvalue from table1

11、几个高级查询运算词

UNION 运算符 

  • UNION 运算符通过组合其他两个结果表(例如 TABLE1 和 TABLE2)并消去表中任何重复行而派生出一个结果表。当 ALL 随 UNION 一起使用时(即 UNION ALL),不消除重复行。两种情况下,派生表的每一行不是来自 TABLE1 就是来自 TABLE2。 

EXCEPT 运算符 

  • EXCEPT运算符通过包括所有在 TABLE1 中但不在 TABLE2 中的行并消除所有重复行而派生出一个结果表。当 ALL 随 EXCEPT 一起使用时(EXCEPT ALL),不消除重复行。

INTERSECT 运算符

  • INTERSECT运算符通过只包括 TABLE1 和 TABLE2 中都有的行并消除所有重复行而派生出一个结果表。当 ALL随 INTERSECT 一起使用时(INTERSECT ALL),不消除重复行。 

注:使用运算词的几个查询结果行必须是一致的。 

12.使用外连接 

  • left (outer) join: 左外连接(左连接),结果集几包括连接表的匹配行,也包括左连接表的所有行。 

       例子:SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c

  • right (outer) join: 右外连接(右连接),结果集既包括连接表的匹配连接行,也包括右连接表的所有行。 
  • full/cross (outer) join: 全外连接,不仅包括符号连接表的匹配行,还包括两个连接表中的所有记录。

13、分组:Group by:
   一张表,一旦分组 完成后,查询后只能得到组相关的信息。
    组相关的信息:(统计信息) count,sum,max,min,avg  分组的标准)
    在SQLServer中分组时:不能以text,ntext,image类型的字段作为分组依据
   在selecte统计函数中的字段,不能和普通的字段放在一起;

14、对数据库进行操作:

  • 分离数据库: sp_detach_db;
  • 附加数据库:sp_attach_db 后接表明,附加需要完整的路径名

15.如何修改数据库的名称:

  • sp_renamedb 'old_name', 'new_name'

16.where子句(用法在第二节有具体例子

第一,运算符 < > >= <=。如查询user表里面语文成绩大于60的所有的人员

  • select * from user where chinese > 60;

第二,in:在范围内。如查询user表里面英语成绩是80、90的人员的信息

  • select * from user where english in (80,90);

第三,and:在where里面如果有多个条件,表示多个条件同时满足。如查询user表里面语文成绩是100,并且英语成绩是30的人员的信息。

  • select * from user where chinese=100 and english=30;

第四,得到区间范围的值。如查询user表里面语文成绩在70-100之间的值:

  • 写法一,select * from user where chinese >=70 and chinese <=100;
  • 写法二,select * from user where chinese between 70 and 100;

第五,like:模糊查询。如:查询user表里面username包含a的人员信息

  • Select * from user where username like '%a%';

17.对表中查询的记录排序order by(第三节会具体讲述)

注: order by写在select语句的最后

第一,升序 order by要排序字段 asc(asc可以省略,默认的情况下就是升序)。如对user表里面查询的数据,根据语文成绩进行升序排列

  • select * from user order by chinese asc;

第二,降序 order by要排序字段 desc。如对user表里面的英语成绩进行降序排列

  • select * from user order by english desc;
     

二、基础操作的综合例子(增删改查):

1.创建和修改表的操作,比如创建一个customers表。

# 创建表
CREATE TABLE customers
(
  cust_id INT NOT NULL AUTO_INCREMENT,
  cust_name CHAR(50) NOT NULL,
  cust_email CHAR(255) NULL,
  PRIMARY KEY (cust_id),   # 主建
  INDEX name_key (cust_name)        # 建索引 索引名和列名 如果不指定索引名,默认列名
) ENGINE=InnoDB CHAR SET=utf8;   #存储引擎和编码
# 删除表
DROP TABLE customers;
# 添加列 默认可为空null
ALTER TABLE customers
ADD cust_phone CHAR(20);
# 删除列
ALTER TABLE customers
DROP COLUMN cust_phone;
# 重命名表
RENAME TABLE customers TO customers2;

2.创建索引的两种方式:

# 添加索引
# 普通索引
ALTER TABLE table_name
ADD INDEX index_name (column_list);
# UNIQUE和PRIMARY KEY索引:规定索引不能包含重复值
ALTER TABLE table_name
ADD UNIQUE (column_list);

CREATE INDEX index_name
ON table_name (column_list);
CREATE UNIQUE INDEX index_name
ON table_name (column_list);

这里需要注意一点:字段名创建的时候,不用单引号,而是反单引号或者不用。 

3.数据插入,是利用INSERT插入行到数据库表中,可有几种方式:插入完整的行,插入行的一部分,插入多行以及插入某些查询的结果。

INSERT INTO customers
VALUES ( '1',
  'Tom',
  NULL,
  NULL
);

注意:这里必须为表中的每个列都提供一个值,没有值并且可以为null的也必须制定null。且值需要用单引号’ ’ 表示。这种方式不安全,应避免使用,因为当表结构变化时,这种方式将出错。

INSERT INTO customers(cust_id,
        cust_name,
        cust_email,
        cust_phone)
VALUES ( '1',
         'Tom',
         NULL,
         NULL
);

上边这种方式更安全,它是前面的列与后边的值一一对应。所以,不一定要按照各个列在实际表中出现的顺序,而且后边为null的列,可以去掉,也就是:

INSERT INTO customers(cust_id,
       cust_name)
VALUES ( '1',
         'Tom'
);

与上边的效果是一样的。但如果,列不允许为null,则必须给定一个非null值。

# 插入多行
INSERT INTO customers(cust_id,
        cust_name)
VALUES (
         '1',
         'Tom'
),
(
         '2',
         'Kim'
);

 插入多行与插入查询数据都比较简单,这里就不再详细解释了,只要确保,列名与后边的值一一对应即可。

4.更新数据

更新表中数据操作,用UPDATE 语句,可分为:更新表中特定行更新表中所有行

要注意WHERE 子句的应用,防止一不小心就更新了表中所有数据。看下面这个例子:

#要更新的表名
UPDATE customers
#列名和要更新的值
SET cust_email = '[email protected]'
#确定要更新行的过滤条件
WHERE cust_id = 1;

如果要更新多个行,可以写成:

UPDATE customers
SET cust_email = '[email protected]',
    cust_phone = '1231'
WHERE cust_id = 1;

这里需要注意:如果用UPDATE 语句更新多行时,如果有一行出现错误,则整个UPDATE操作都被取消(即如果第三行出错,那么前面操作成功的语句回滚,撤销操作)

当然,如果你的想法比较强硬,想要出现错误的也让其他的语句继续更新,可使用 IGNORE 关键字。即:UPDATE IGNORE。

 5.删除操作

在一个表中删除数据,使用DELETE 语句,删除特定行,删除多有行。要注意WHERE 过滤条件的使用,安全性。

DELETE FROM customers
WHERE cust_name = 1;

注意: 如果没有WHERE子句,则更新和删除操作将应用到所有的行。

三、数据检索

1.简单检索:LIMIT、ORDER BY

# 检索多个列
SELECT cust_id, cust_name, cust_email
FROM customers;
# 检索所有的列
SELECT cust_id, cust_name, cust_email, cust_phone
FROM customers;
SELECT *
FROM customers;

注意:如果不是需要表中的每个列,不要使用SELECT * 通配符操作,会降低检索性能。 


1.1若某行的值由重复,则检索出不同的行的sql语句:

# 检索不同的行
SELECT DISTINCT cust_name
FROM customers;

1.2限制结果,返回特定的行和行数:

# 检索限制结果
# LIMIT 第一个数为开始的行数,第二个数为要检索的行数
# 从第0行(代表第一行)开始
SELECT cust_name
FROM customers
LIMIT 5;
# 从第5行(实际表中的第六行)开始,显示5行
SELECT cust_name
FROM customers
LIMIT 5, 5;

注意:上边检索出来的数据是无序的,也并不与实际表中的顺序一一对应,我们可认为检索出来的数据的顺序是无意义的。 

为了更好的理解如何运用上面的方法进行检索,举个栗子~

假设有一个products,有id,价格,名称字段。 我们来看看关于它的一些检索方式:

# 默认ASC 升序
SELECT prod_name
FROM products
ORDER BY prod_price;
# DESC 降序
SELECT prod_name
FROM products
ORDER BY prod_price DESC;
# 按多个列排序 先按价格,再按名称
SELECT prod_name
FROM products
ORDER BY prod_price, prod_name;
# 按多个列排序 DESC只对它前面的列有作用,即先按价格降序,再按名称升序
SELECT prod_name
FROM products
ORDER BY prod_price DESC , prod_name;
# DESC 降序,然后再取第0行(0,1 0行开始取1行)
SELECT prod_name
FROM products
ORDER BY prod_price DESC
LIMIT 1;

这里注意:ORDER BY 子句,要保证它位于FROM子句之后,在WHERE之后,如果使用LIMIT,它必须位于ORDER BY之后。 

2.数据过滤 条件/逻辑运算符 

最简单的数据过滤就是使用WHERE 子句。WHERE 子句的条件操作符有:= 等于,<> != 不等于,< 小于,<= 小于等于, >大于,> 大于等于,BETWEEN AND,介于指定的两个值之间,IS NULL 空值检查。

# WHERE 子句
SELECT prod_name, prod_price
FROM products
WHERE prod_price BETWEEN 5 AND 10;

WHERE 的逻辑运算符有AND ,OR, NOT,IN。

2.1AND、OR的具体用法为:

# 检索出由1003供应商生成且价格<=10的商品信息
SELECT prod_id, prod_price, prod_name
FROM products
WHERE vend_id = 1003 AND prod_price <= 10;
# 检索出由1003或1002供应商生成的商品
SELECT prod_id, prod_price, prod_name
FROM products
WHERE vend_id = 1003 OR vend_id = 1002;

注意:AND 的操作符优先级要高于OR,在AND 和 OR 同时出现时,会优先处理AND的逻辑,所以为了避免歧义,要尽量使用括号( )。  

2.2 IN和NOT IN 的用法为:

# 检索出由1003或1002供应商生成的商品 并排序
SELECT prod_id, prod_price, prod_name
FROM products
WHERE vend_id IN (1002, 1003)
ORDER BY prod_name;
# 检索出除了1003或1002供应商生成的商品  并排序
SELECT prod_id, prod_price, prod_name
FROM products
WHERE vend_id NOT IN (1002, 1003)
ORDER BY prod_name;

3.利用通配符进行数据过滤

3.1LIKE + 通配符来进行过滤。

使用该方法,必须使用LIKE 操作符,否则就是直接相等匹配了。

# 通配符 % 表示匹配0个或任意个字符 但不可以匹配null
# 匹配以jet为开头的任意字符
SELECT prod_id, prod_name
FROM products
WHERE prod_name LIKE 'jet%';
# 匹配包含jet的任意字符
SELECT prod_id, prod_name
FROM products
WHERE prod_name LIKE '%jet%';
# 匹配以s开头e结尾的字符
SELECT prod_id, prod_name
FROM products
WHERE prod_name LIKE 's%e';
# 通配符 _ 表示匹配单个字符
SELECT prod_id, prod_name
FROM products
WHERE prod_name LIKE '_jet';

注意:通配符来匹配时一般效率较低。 

使用正则表达式进行匹配:

SELECT prod_id, prod_name
FROM products
WHERE prod_name REGEXP '.000';

4.汇合数据

使用聚集函数来对数据进行汇总。MySQL提供了5种的聚集函数:

  • AVG( ) 返回某列的平均值
  • COUNT( ) 返回某列的行数
  • MAX( ) 返回某列的最大值
  • MIN( ) 返回某列的最小值
  • SUM( ) 返回某列值之和
# AVG()
SELECT AVG(prod_price) AS avg_price
FROM products;
# COUNT() 返回行数
# COUNT(*) 对所有的行计数 不管各列中有什么值 不忽略null
SELECT COUNT(*)
FROM products;
# COUNT(列名)  忽略null
SELECT COUNT(cust_email)
FROM customers;

 注:AS用来起别名。

其他的几个函数用法类似,不再举例。

5.数据分组 

对数据进行分组的理解是:假设一个供应商A,它生产了很多产品,我们可以按照供应商来进行分组,并且使用聚集函数来统计分组信息。

# 按vend_id分组,并统计每组的行数
SELECT vend_id, count(*) 
FROM products
GROUP BY vend_id;

过滤分组,利用HAVING

# 过滤分组,返回行数大于等于2的分组 并按行数排序
SELECT vend_id, count(*) AS odertotal
FROM products
GROUP BY vend_id
HAVING count(*) >= 2
ORDER BY odertotal;

 6.使用子查询

关系型数据库的核心就是表,假设有两个表,存储不同的信息,利用子查询。子查询就是把一条SELECT 语句返回的结果用于另一条SELECT的WHERE子句。 
子查询一般是与IN操作符结合使用的。

# 子查询.从oderitems表中查询prod_id的订单号,然后返回此订单号的客户号
SELECT cust_id 
FROM orders
WHERE order_num IN (SELECT order_num
                     FROM oderitems
                     WHERE prod_id = 'TTT');

 另外,子查询可填充计算列。

7. 联结表

 关系表的设计就是要保证把信息分解成多个表,一类数据一个表。主键:唯一标识,外键:外键为某个表中的某一列(是另一表的主键)。

# 联结
SELECT vend_name, prod_name, prod_price
FROM vendors, products
WHERE vendors.vend_id = products.prod_id
# 用INNER JOIN 明确表示联结
SELECT vend_name, prod_name, prod_price
FROM vendors INNER JOIN products
ON vendors.vend_id = products.prod_id

 其实,这个联结可以用子查询来实现。

8.组合查询

利用UNION 操作符,将多条SELECT 语句组合成一个结果集。这里不详细解释了。

四、提升

1、复制表(只复制结构,源表名:a 新表名:b) (Access可用)

  • 法一:select * into b from a where 1<>1(仅用于SQlServer)
  • 法二:select top 0 * into b from a

2、拷贝表(拷贝数据,源表名:a 目标表名:b) (Access可用)

  • insert into b(a, b, c) select d,e,f from b;

3、跨数据库之间表的拷贝(具体数据使用绝对路径) (Access可用)

  • insert into b(a, b, c) select d,e,f from b in ‘具体数据库’ where 条件

例子:..from b in '"&Server.MapPath(".")&"\data.mdb" &"' where..

4、子查询(表名1:a 表名2:b)

  • select a,b,c from a where a IN (select d from b ) 或者: select a,b,c from a where a IN (1,2,3)

5、显示文章、提交人和最后回复时间

  • select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b

6、外连接查询(表名1:a 表名2:b)

  • select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c

7、在线视图查询(表名1:a )

  • select * from (SELECT a,b,c FROM a) T where t.a > 1;

8、between的用法,between限制查询数据范围时包括了边界值,not between不包括。

  • select * from table1 where time between time1 and time2
  • select a,b,c, from table1 where a not between 数值1 and 数值2

9、in 的使用方法

  • select * from table1 where a [not] in (‘值1’,’值2’,’值4’,’值6’)

10、两张关联表,删除主表中已经在副表中没有的信息 

  • delete from table1 where not exists ( select * from table2 where table1.field1=table2.field1 )

11、四表联查问题:

  • select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where .....

12、日程安排提前五分钟提醒 

  • SQL: select * from 日程安排 where datediff('minute',f开始时间,getdate())>5

13、一条sql 语句搞定数据库分页

  • select top 10 b.* from (select top 20 主键字段,排序字段 from 表名 order by 排序字段 desc) a,表名 b where b.主键字段 = a.主键字段 order by a.排序字段

具体实现:

关于数据库分页:

  declare @start int,@end int

 @sql  nvarchar(600)

 set @sql=’select top’+str(@end-@start+1)+’+from T where rid not in(select top’+str(@str-1)+’Rid from T where Rid>-1)’

 exec sp_executesql @sql

注意:在top后不能直接跟一个变量,所以在实际应用中只有这样的进行特殊的处理。Rid为一个标识列,如果top后还有具体的字段,这样做是非常有好处的。因为这样可以避免 top的字段如果是逻辑索引的,查询的结果后实际表中的不一致(逻辑索引中的数据有可能和数据表中的不一致,而查询时如果处在索引则首先查询索引

14、前10条记录

  • select top 10 * form table1 where 范围

15、选择在每一组b值相同的数据中对应的a最大的记录的所有信息(类似这样的用法可以用于论坛每月排行榜,每月热销产品分析,按科目成绩排名,等等.)

  • select a,b,c from tablename ta where a=(select max(a) from tablename tb where tb.b=ta.b)

16、包括所有在 TableA中但不在 TableB和TableC中的行并消除所有重复行而派生出一个结果表

  • (select a from tableA ) except (select a from tableB) except (select a from tableC)

17、随机取出10条数据

  • select top 10 * from tablename order by newid()

18、随机选择记录

  • select newid()

19、删除重复记录

1)

​​​​​​​delete from tablename where id not in (select max(id) from tablename group by col1,col2,...)

2),

select distinct * into temp from tablename

  delete from tablename

  insert into tablename select * from temp

评价: 这种操作牵连大量的数据的移动,这种做法不适合大容量但数据操作
3),例如:在一个外部表中导入数据,由于某些原因第一次只导入了一部分,但很难判断具体位置,这样只有在下一次全部导入,这样也就产生好多重复的字段,怎样删除重复字段。

alter table tablename
--添加一个自增列
add  column_b int identity(1,1)
 delete from tablename where column_b not in(
select max(column_b)  from tablename group by column1,column2,...)
alter table tablename drop column column_b

20、列出数据库里所有的表名

  • select name from sysobjects where type='U' // U代表用户

21、列出表里的所有的列名

  • select name from syscolumns where id=object_id('TableName')

22、列示type、vender、pcs字段,以type字段排列,case可以方便地实现多重选择,类似select 中的case。

  • select type,sum(case vender when 'A' then pcs else 0 end),sum(case vender when 'C' then pcs else 0 end),sum(case vender when 'B' then pcs else 0 end) FROM tablename group by type

显示结果:
type vender pcs
电脑 A 1
电脑 A 1
光盘 B 2
光盘 A 2
手机 B 3
手机 C 3

23、初始化表table1

  • TRUNCATE TABLE table1

24、选择从10到15的记录

  • select top 5 * from (select top 15 * from table order by id asc) table_别名 order by id desc

 五、技巧

1、1=1,1=2的使用,在SQL语句组合时用的较多

“where 1=1” 是表示选择全部    “where 1=2”全部不选,
如:

if @strWhere !='' 
begin
set @strSQL = 'select count(*) as Total from [' + @tblName + '] where ' + @strWhere 
end
else 
begin
set @strSQL = 'select count(*) as Total from [' + @tblName + ']' 
end

我们可以直接写成

错误!未找到目录项。

set @strSQL = 'select count(*) as Total from [' + @tblName + '] where 1=1 安定 '+ @strWhere 

2、收缩数据库
--重建索引

DBCC REINDEX
DBCC INDEXDEFRAG


--收缩数据和日志

DBCC SHRINKDB
DBCC SHRINKFILE

3、压缩数据库

dbcc shrinkdatabase(dbname)

4、转移数据库给新用户以已存在用户权限

exec sp_change_users_login 'update_one','newname','oldname'
go

5、检查备份集

RESTORE VERIFYONLY from disk='E:\dvbbs.bak'

6、修复数据库
 

ALTER DATABASE [dvbbs] SET SINGLE_USER
GO
DBCC CHECKDB('dvbbs',repair_allow_data_loss) WITH TABLOCK
GO
ALTER DATABASE [dvbbs] SET MULTI_USER
GO

7、日志清除

SET NOCOUNT ON
DECLARE @LogicalFileName sysname,
 @MaxMinutes INT,
 @NewSize INT


USE tablename -- 要操作的数据库名
SELECT  @LogicalFileName = 'tablename_log', -- 日志文件名
@MaxMinutes = 10, -- Limit on time allowed to wrap log.
 @NewSize = 1  -- 你想设定的日志文件的大小(M)

Setup / initialize
DECLARE @OriginalSize int
SELECT @OriginalSize = size 
 FROM sysfiles
 WHERE name = @LogicalFileName
SELECT 'Original Size of ' + db_name() + ' LOG is ' + 
 CONVERT(VARCHAR(30),@OriginalSize) + ' 8K pages or ' + 
 CONVERT(VARCHAR(30),(@OriginalSize*8/1024)) + 'MB'
 FROM sysfiles
 WHERE name = @LogicalFileName
CREATE TABLE DummyTrans
 (DummyColumn char (8000) not null)


DECLARE @Counter    INT,
 @StartTime DATETIME,
 @TruncLog   VARCHAR(255)
SELECT @StartTime = GETDATE(),
 @TruncLog = 'BACKUP LOG ' + db_name() + ' WITH TRUNCATE_ONLY'

DBCC SHRINKFILE (@LogicalFileName, @NewSize)
EXEC (@TruncLog)
-- Wrap the log if necessary.
WHILE @MaxMinutes > DATEDIFF (mi, @StartTime, GETDATE()) -- time has not expired
 AND @OriginalSize = (SELECT size FROM sysfiles WHERE name = @LogicalFileName)  
 AND (@OriginalSize * 8 /1024) > @NewSize  
 BEGIN -- Outer loop.
SELECT @Counter = 0
 WHILE   ((@Counter < @OriginalSize / 16) AND (@Counter < 50000))
 BEGIN -- update
 INSERT DummyTrans VALUES ('Fill Log') DELETE DummyTrans
 SELECT @Counter = @Counter + 1
 END
 EXEC (@TruncLog)  
 END
SELECT 'Final Size of ' + db_name() + ' LOG is ' +
 CONVERT(VARCHAR(30),size) + ' 8K pages or ' + 
 CONVERT(VARCHAR(30),(size*8/1024)) + 'MB'
 FROM sysfiles 
 WHERE name = @LogicalFileName
DROP TABLE DummyTrans
SET NOCOUNT OFF

8、说明:更改某个表

exec sp_changeobjectowner 'tablename','dbo'

9、存储更改全部表

CREATE PROCEDURE dbo.User_ChangeObjectOwnerBatch
@OldOwner as NVARCHAR(128),
@NewOwner as NVARCHAR(128)
AS

DECLARE @Name    as NVARCHAR(128)
DECLARE @Owner   as NVARCHAR(128)
DECLARE @OwnerName   as NVARCHAR(128)

DECLARE curObject CURSOR FOR 
select 'Name'    = name,
   'Owner'    = user_name(uid)
from sysobjects
where user_name(uid)=@OldOwner
order by name

OPEN   curObject
FETCH NEXT FROM curObject INTO @Name, @Owner
WHILE(@@FETCH_STATUS=0)
BEGIN     
if @Owner=@OldOwner 
begin
   set @OwnerName = @OldOwner + '.' + rtrim(@Name)
   exec sp_changeobjectowner @OwnerName, @NewOwner
end
-- select @name,@NewOwner,@OldOwner

FETCH NEXT FROM curObject INTO @Name, @Owner
END

close curObject
deallocate curObject
GO

10、SQL SERVER中直接循环写入数据
 

declare @i int
set @i=1
while @i<30
begin
    insert into test (userid) values(@i)
    set @i=@i+1
end


案例
有如下表,要求就裱中所有沒有及格的成績,在每次增長0.1的基礎上,使他們剛好及格:

Name Score
Zhangsan 80
Lisi 59
Wangwu 50
Songquan 69
while((select min(score) from tb_table)<60)
begin

update tb_table set score =score*1.01

where score<60

if  (select min(score) from tb_table)>60

  break

 else

    continue

end

 

六、数据开发-经典例题

1.按姓氏笔画排序:

Select * From TableName Order By CustomerName Collate Chinese_PRC_Stroke_ci_as //从少到多

2.数据库加密:

select encrypt('原始密码')
select pwdencrypt('原始密码')
select pwdcompare('原始密码','加密后密码') = 1--相同;否则不相同 encrypt('原始密码')
select pwdencrypt('原始密码')
select pwdcompare('原始密码','加密后密码') = 1--相同;否则不相同

3.取回表中字段:

declare @list varchar(1000),
@sql nvarchar(1000) 
select @list=@list+','+b.name from sysobjects a,syscolumns b where a.id=b.id and a.name='表A'
set @sql='select '+right(@list,len(@list)-1)+' from 表A' 
exec (@sql)

4.查看硬盘分区:

EXEC master..xp_fixeddrives

5.比较A,B表是否相等:

if (select checksum_agg(binary_checksum(*)) from A)
     =
    (select checksum_agg(binary_checksum(*)) from B)
print '相等'
else
print '不相等'

6.杀掉所有的事件探察器进程:

DECLARE hcforeach CURSOR GLOBAL FOR SELECT 'kill '+RTRIM(spid) FROM master.dbo.sysprocesses
WHERE program_name IN('SQL profiler',N'SQL 事件探查器')
EXEC sp_msforeach_worker '?'

 

7.记录搜索:
 开头到N条记录
Select Top N * From 表
-------------------------------
NM条记录(要有主索引ID)
Select Top M-N * From 表 Where ID in (Select Top M ID From 表) Order by ID   Desc
----------------------------------
N到结尾记录
Select Top N * From 表 Order by ID Desc
案例
例如1:一张表有一万多条记录,表的第一个字段 RecID 是自增长字段, 写一个SQL语句, 找出表的第31到第40个记录。

 select top 10 recid from A where recid not  in(select top 30 recid from A)

分析:如果这样写会产生某些问题,如果recid在表中存在逻辑索引。

    select top 10 recid from A where……是从索引中查找,而后面的select top 30 recid from A则在数据表中查找,这样由于索引中的顺序有可能和数据表中的不一致,这样就导致查询到的不是本来的欲得到的数据。

解决方案

1,用order by select top 30 recid from A order by ricid 如果该字段不是自增长,就会出现问题

2,在那个子查询中也加条件:select top 30 recid from A where recid>-1

例2:查询表中的最后以条记录,并不知道这个表共有多少数据,以及表结构。

set @s = 'select top 1 * from T   where pid not in (select top ' + str(@count-1) + ' pid  from  T)'

print @s      exec  sp_executesql  @s

9:获取当前数据库中的所有用户表

select Name from sysobjects where xtype='u' and status>=0

10:获取某一个表的所有字段

  • select name from syscolumns where id=object_id('表名')
  • select name from syscolumns where id in (select id from sysobjects where type = 'u' and name = '表名')

两种方式的效果相同

11:查看与某一个表相关的视图、存储过程、函数

select a.* from sysobjects a, syscomments b where a.id = b.id and b.text like '%表名%'

12:查看当前数据库中所有存储过程

select name as 存储过程名称 from sysobjects where xtype='P'

13:查询用户创建的所有数据库
select * from master..sysdatabases D where sid not in(select sid from master..syslogins where name='sa')
或者
select dbid, name AS DB_NAME from master..sysdatabases where sid <> 0x01

14:查询某一个表的字段和数据类型

select column_name,data_type from information_schema.columns
where table_name = '表名'

15:不同服务器数据库之间的数据操作

--创建链接服务器

exec sp_addlinkedserver   'ITSV ', ' ', 'SQLOLEDB ', '远程服务器名或ip地址 '

exec sp_addlinkedsrvlogin  'ITSV ', 'false ',null, '用户名 ', '密码 '

--查询示例

select * from ITSV.数据库名.dbo.表名

--导入示例

select * into 表 from ITSV.数据库名.dbo.表名

--以后不再使用时删除链接服务器

exec sp_dropserver  'ITSV ', 'droplogins '

 

--连接远程/局域网数据(openrowset/openquery/opendatasource)

--1、openrowset

--查询示例

select * from openrowset( 'SQLOLEDB ', 'sql服务器名 '; '用户名 '; '密码 ',数据库名.dbo.表名)

--生成本地表

select * into 表 from openrowset( 'SQLOLEDB ', 'sql服务器名 '; '用户名 '; '密码 ',数据库名.dbo.表名)

--把本地表导入远程表

insert openrowset( 'SQLOLEDB ', 'sql服务器名 '; '用户名 '; '密码 ',数据库名.dbo.表名)

select *from 本地表

--更新本地表

update b

set b.列A=a.列A

 from openrowset( 'SQLOLEDB ', 'sql服务器名 '; '用户名 '; '密码 ',数据库名.dbo.表名)as a inner join 本地表 b

on a.column1=b.column1

--openquery用法需要创建一个连接

--首先创建一个连接创建链接服务器

exec sp_addlinkedserver   'ITSV ', ' ', 'SQLOLEDB ', '远程服务器名或ip地址 '

--查询

select *

FROM openquery(ITSV,  'SELECT *  FROM 数据库.dbo.表名 ')

--把本地表导入远程表

insert openquery(ITSV,  'SELECT *  FROM 数据库.dbo.表名 ')

select * from 本地表

--更新本地表

update b

set b.列B=a.列B

FROM openquery(ITSV,  'SELECT * FROM 数据库.dbo.表名 ') as a 

inner join 本地表 b on a.列A=b.列A

--3、opendatasource/openrowset

SELECT   *

FROM   opendatasource( 'SQLOLEDB ',  'Data Source=ip/ServerName;User ID=登陆名;Password=密码 ' ).test.dbo.roy_ta

--把本地表导入远程表

insert opendatasource( 'SQLOLEDB ',  'Data Source=ip/ServerName;User ID=登陆名;Password=密码 ').数据库.dbo.表名

select * from 本地表 

  

好啦,以上就是关于SQL语句的一些总结,后期将继续更新。

Biu~~~~~~~~~~~~~~~~~~~~宫å´éªé¾ç«è¡¨æå|é¾ç«gifå¾è¡¨æåä¸è½½å¾ç~~~~~~~~~~~~~~~~~~~~~~pia!

参考文章:

http://www.cnblogs.com/yubinfeng/archive/2010/11/02/1867386.html

https://blog.csdn.net/u013679744/article/details/76087429

猜你喜欢

转载自blog.csdn.net/Searchin_R/article/details/84780551