日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

SQL學習

發布時間:2023/12/1 数据库 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SQL學習 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.模糊表名的聯合查詢..

create table tz2008_1_1(id int,name varchar(50))
insert into tz2008_1_1 select 1,'a'
create table tz2008_1_2(id int,name varchar(50))
insert into tz2008_1_2 select 2,'b'
create table tz2008_1_3(id int,name varchar(50))
insert into tz2008_1_3 select 3,'c'


declare @sql varchar(8000)
select @sql=isnull(@sql+' union all ','')+' select * from ['+name+']'
from sysobjects where xtype='u' and name like 'tz2008%'
exec(@sql)


2.

--查詢表的默認值
if object_id('tb') is not null
drop table tb
go
create table tb(id int,name varchar(50) default 'abc',num int default 5)
insert into tb(id) select 1
insert into tb select 1,'oo',100
insert into tb(id,name) select 1,'oo'
go
declare @tbname varchar(50)
set @tbname='tb'--表名
select @tbname as tbname,c.name as colname,replace(replace(replace(replace(b.[text],'(''',''),''')',''),'((',''),'))','') as defaultvalue
from sysconstraints a join syscomments b on a.constid=b.id
join syscolumns c on a.id=c.id and a.colid=c.colid
where a.id=object_id(@tbname) and object_name(a.constid) like '%df%'


3.

--存儲過程語句查詢
if object_id('proc_ttt') is not null
drop proc proc_ttt
go
create proc proc_ttt
as
select 1 union select 2
go

select [text] from syscomments
where id=object_id('proc_ttt')


EXEC SP_HELPTEXT 'proc_ttt'


4.

--通過身份證獲得戶籍 create function f_getcityfromcid (@cid varchar(18)) returns varchar(50) as begin declare @acity varchar(1000) set @acity = '____,____,____,____,____,____,____,____,____,____,____,北京__,天津__,河北__,山西__,內蒙古_,____,____,____,____,____,遼寧__,吉林__,黑龍江_,____,____,____,____,____,____,____,上海__,江蘇__,浙江__,安微__,福建__,江西__,山東__,____,____,____,河南__,湖北__,湖南__,廣東__,廣西__,海南__,____,____,____,重慶__,四川__,貴州__,云南__,西藏__,____,____,____,____,____,____,陜西__,甘肅__,青海__,寧夏__,新疆__,____,____,____,____,____,臺灣__,____,____,____,____,____,____,____,____,____,香港__,澳門__,____,____,____,____,____,____,____,____,國外__,' set @cid = upper(@cid) IF (len(@cid) <> 18 OR patindex('%[^0-9X]%',@cid) > 0) RETURN '你小子騙我,這不是合法的身份證' IF substring(@acity,cast(left(@cid,2) as int)* 5+1,4) = '' RETURN '你小子騙我,這身份證的地區碼不存在' RETURN '這小子是:'+replace(substring(@acity,cast(left(@cid,2) as int)* 5+1,4),'_','') end go select dbo.f_getcityfromcid('32108519760502ttt9') /* -------------------------------------------------- 你小子騙我,這不是合法的身份證 (所影響的行數為 1 行) */ select dbo.f_getcityfromcid('32108519****026**9') /* -------------------------------------------------- 這小子是:江蘇 (所影響的行數為 1 行) */ drop function f_getcityfromcid


5.

--隨機選擇一個小于等于500的組合 declare @tb table(id int,num int) insert into @tb select 1,1000 insert into @tb select 2,100 insert into @tb select 3,500 insert into @tb select 4,200 insert into @tb select 5,200 insert into @tb select 6,50 insert into @tb select 7,150 insert into @tb select 8,80 insert into @tb select 9,70 declare @idtb table(id int) declare @num int,@id int,@sum int set @sum=0 while @sum<>500 begin select top 1 @id=id,@num=num from @tb where num<=500 order by newid() if @num=500 insert into @idtb select @id else if not exists(select 1 from @idtb where id=@id) insert into @idtb select @id select @sum=sum(num) from @tb where id in(select id from @idtb) if(@sum>500) begin delete @idtb end end select * from @tb where id in( select id from @idtb)


6.

/*
標題:普通行列轉換(version 2.0)
作者:愛新覺羅.毓華(十八年風雨,守得冰山雪蓮花開)
時間:2008-03-09
地點:廣東深圳
說明:普通行列轉換(version 1.0)僅針對sql server 2000提供靜態和動態寫法,version 2.0增加sql server 2005的有關寫法。

問題:假設有張學生成績表(tb)如下:
姓名 課程 分數
張三 語文 74
張三 數學 83
張三 物理 93
李四 語文 74
李四 數學 84
李四 物理 94
想變成(得到如下結果):
姓名 語文 數學 物理
---- ---- ---- ----
李四 74 84 94
張三 74 83 93
-------------------
*/

create table tb(姓名 varchar(10) , 課程 varchar(10) , 分數 int)
insert into tb values('張三' , '語文' , 74)
insert into tb values('張三' , '數學' , 83)
insert into tb values('張三' , '物理' , 93)
insert into tb values('李四' , '語文' , 74)
insert into tb values('李四' , '數學' , 84)
insert into tb values('李四' , '物理' , 94)
go

--SQL SERVER 2000 靜態SQL,指課程只有語文、數學、物理這三門課程。(以下同)
select 姓名 as 姓名 ,
max(case 課程 when '語文' then 分數 else 0 end) 語文,
max(case 課程 when '數學' then 分數 else 0 end) 數學,
max(case 課程 when '物理' then 分數 else 0 end) 物理
from tb
group by 姓名

--SQL SERVER 2000 動態SQL,指課程不止語文、數學、物理這三門課程。(以下同)
declare @sql varchar(8000)
set @sql = 'select 姓名 '
select @sql = @sql + ' , max(case 課程 when ''' + 課程 + ''' then 分數 else 0 end) [' + 課程 + ']'
from (select distinct 課程 from tb) as a
set @sql = @sql + ' from tb group by 姓名'
exec(@sql)

--SQL SERVER 2005 靜態SQL。
select * from (select * from tb) a pivot (max(分數) for 課程 in (語文,數學,物理)) b

--SQL SERVER 2005 動態SQL。
declare @sql varchar(8000)
select @sql = isnull(@sql + '],[' , '') + 課程 from tb group by 課程
set @sql = '[' + @sql + ']'
exec ('select * from (select * from tb) a pivot (max(分數) for 課程 in (' + @sql + ')) b')

---------------------------------

/*
問題:在上述結果的基礎上加平均分,總分,得到如下結果:
姓名 語文 數學 物理 平均分 總分
---- ---- ---- ---- ------ ----
李四 74 84 94 84.00 252
張三 74 83 93 83.33 250
*/

--SQL SERVER 2000 靜態SQL。
select 姓名 姓名,
max(case 課程 when '語文' then 分數 else 0 end) 語文,
max(case 課程 when '數學' then 分數 else 0 end) 數學,
max(case 課程 when '物理' then 分數 else 0 end) 物理,
cast(avg(分數*1.0) as decimal(18,2)) 平均分,
sum(分數) 總分
from tb
group by 姓名

--SQL SERVER 2000 動態SQL。
declare @sql varchar(8000)
set @sql = 'select 姓名 '
select @sql = @sql + ' , max(case 課程 when ''' + 課程 + ''' then 分數 else 0 end) [' + 課程 + ']'
from (select distinct 課程 from tb) as a
set @sql = @sql + ' , cast(avg(分數*1.0) as decimal(18,2)) 平均分 , sum(分數) 總分 from tb group by 姓名'
exec(@sql)

--SQL SERVER 2005 靜態SQL。
select m.* , n.平均分 , n.總分 from
(
select * from (select * from tb) a pivot (max(分數) for 課程 in (語文,數學,物理)) b) m,
(
select 姓名 , cast(avg(分數*1.0) as decimal(18,2)) 平均分 , sum(分數) 總分 from tb group by 姓名) n
where m.姓名 = n.姓名

--SQL SERVER 2005 動態SQL。
declare @sql varchar(8000)
select @sql = isnull(@sql + ',' , '') + 課程 from tb group by 課程
exec ('select m.* , n.平均分 , n.總分 from
(select * from (select * from tb) a pivot (max(分數) for 課程 in (
' + @sql + ')) b) m ,
(select 姓名 , cast(avg(分數*1.0) as decimal(18,2)) 平均分 , sum(分數) 總分 from tb group by 姓名) n
where m.姓名 = n.姓名
')

drop table tb

------------------
--
----------------

/*
問題:如果上述兩表互相換一下:即表結構和數據為:
姓名 語文 數學 物理
張三 74  83  93
李四 74  84  94
想變成(得到如下結果):
姓名 課程 分數
---- ---- ----
李四 語文 74
李四 數學 84
李四 物理 94
張三 語文 74
張三 數學 83
張三 物理 93
--------------
*/

create table tb(姓名 varchar(10) , 語文 int , 數學 int , 物理 int)
insert into tb values('張三',74,83,93)
insert into tb values('李四',74,84,94)
go

--SQL SERVER 2000 靜態SQL。
select * from
(
select 姓名 , 課程 = '語文' , 分數 = 語文 from tb
union all
select 姓名 , 課程 = '數學' , 分數 = 數學 from tb
union all
select 姓名 , 課程 = '物理' , 分數 = 物理 from tb
) t
order by 姓名 , case 課程 when '語文' then 1 when '數學' then 2 when '物理' then 3 end

--SQL SERVER 2000 動態SQL。
--
調用系統表動態生態。
declare @sql varchar(8000)
select @sql = isnull(@sql + ' union all ' , '' ) + ' select 姓名 , [課程] = ' + quotename(Name , '''') + ' , [分數] = ' + quotename(Name) + ' from tb'
from syscolumns
where name! = N'姓名' and ID = object_id('tb') --表名tb,不包含列名為姓名的其它列
order by colid asc
exec(@sql + ' order by 姓名 ')

--SQL SERVER 2005 動態SQL。
select 姓名 , 課程 , 分數 from tb unpivot (分數 for 課程 in([語文] , [數學] , [物理])) t

--SQL SERVER 2005 動態SQL,同SQL SERVER 2000 動態SQL。

--------------------
/*

問題:在上述的結果上加個平均分,總分,得到如下結果:
姓名 課程 分數
---- ------ ------
李四 語文 74.00
李四 數學 84.00
李四 物理 94.00
李四 平均分 84.00
李四 總分 252.00
張三 語文 74.00
張三 數學 83.00
張三 物理 93.00
張三 平均分 83.33
張三 總分 250.00
------------------
*/

select * from
(
select 姓名 as 姓名 , 課程 = '語文' , 分數 = 語文 from tb
union all
select 姓名 as 姓名 , 課程 = '數學' , 分數 = 數學 from tb
union all
select 姓名 as 姓名 , 課程 = '物理' , 分數 = 物理 from tb
union all
select 姓名 as 姓名 , 課程 = '平均分' , 分數 = cast((語文 + 數學 + 物理)*1.0/3 as decimal(18,2)) from tb
union all
select 姓名 as 姓名 , 課程 = '總分' , 分數 = 語文 + 數學 + 物理 from tb
) t
order by 姓名 , case 課程 when '語文' then 1 when '數學' then 2 when '物理' then 3 when '平均分' then 4 when '總分' then 5 end

drop table tb


7.

--按某一字段分組取最大(小)值所在行的數據
--
(愛新覺羅.毓華(十八年風雨,守得冰山雪蓮花開) 2007-10-23于浙江杭州)
/*

數據如下:
name val memo
a 2 a2(a的第二個值)
a 1 a1--a的第一個值
a 3 a3:a的第三個值
b 1 b1--b的第一個值
b 3 b3:b的第三個值
b 2 b2b2b2b2
b 4 b4b4
b 5 b5b5b5b5b5
*/
--創建表并插入數據:
create table tb(name varchar(10),val int,memo varchar(20))
insert into tb values('a', 2, 'a2(a的第二個值)')
insert into tb values('a', 1, 'a1--a的第一個值')
insert into tb values('a', 3, 'a3:a的第三個值')
insert into tb values('b', 1, 'b1--b的第一個值')
insert into tb values('b', 3, 'b3:b的第三個值')
insert into tb values('b', 2, 'b2b2b2b2')
insert into tb values('b', 4, 'b4b4')
insert into tb values('b', 5, 'b5b5b5b5b5')
go

--一、按name分組取val最大的值所在行的數據。
--
方法1:
select a.* from tb a where val = (select max(val) from tb where name = a.name) order by a.name
--方法2:
select a.* from tb a where not exists(select 1 from tb where name = a.name and val > a.val)
--方法3:
select a.* from tb a,(select name,max(val) val from tb group by name) b where a.name = b.name and a.val = b.val order by a.name
--方法4:
select a.* from tb a inner join (select name , max(val) val from tb group by name) b on a.name = b.name and a.val = b.val order by a.name
--方法5
select a.* from tb a where 1 > (select count(*) from tb where name = a.name and val > a.val ) order by a.name
/*
name val memo
---------- ----------- --------------------
a 3 a3:a的第三個值
b 5 b5b5b5b5b5
*/

--二、按name分組取val最小的值所在行的數據。
--
方法1:
select a.* from tb a where val = (select min(val) from tb where name = a.name) order by a.name
--方法2:
select a.* from tb a where not exists(select 1 from tb where name = a.name and val < a.val)
--方法3:
select a.* from tb a,(select name,min(val) val from tb group by name) b where a.name = b.name and a.val = b.val order by a.name
--方法4:
select a.* from tb a inner join (select name , min(val) val from tb group by name) b on a.name = b.name and a.val = b.val order by a.name
--方法5
select a.* from tb a where 1 > (select count(*) from tb where name = a.name and val < a.val) order by a.name
/*
name val memo
---------- ----------- --------------------
a 1 a1--a的第一個值
b 1 b1--b的第一個值
*/

--三、按name分組取第一次出現的行所在的數據。
select a.* from tb a where val = (select top 1 val from tb where name = a.name) order by a.name
/*
name val memo
---------- ----------- --------------------
a 2 a2(a的第二個值)
b 1 b1--b的第一個值
*/

--四、按name分組隨機取一條數據。
select a.* from tb a where val = (select top 1 val from tb where name = a.name order by newid()) order by a.name
/*
name val memo
---------- ----------- --------------------
a 1 a1--a的第一個值
b 5 b5b5b5b5b5
*/

--五、按name分組取最小的兩個(N個)val
select a.* from tb a where 2 > (select count(*) from tb where name = a.name and val < a.val ) order by a.name,a.val
select a.* from tb a where val in (select top 2 val from tb where name=a.name order by val) order by a.name,a.val
select a.* from tb a where exists (select count(*) from tb where name = a.name and val < a.val having Count(*) < 2) order by a.name
/*
name val memo
---------- ----------- --------------------
a 1 a1--a的第一個值
a 2 a2(a的第二個值)
b 1 b1--b的第一個值
b 2 b2b2b2b2
*/

--六、按name分組取最大的兩個(N個)val
select a.* from tb a where 2 > (select count(*) from tb where name = a.name and val > a.val ) order by a.name,a.val
select a.* from tb a where val in (select top 2 val from tb where name=a.name order by val desc) order by a.name,a.val
select a.* from tb a where exists (select count(*) from tb where name = a.name and val > a.val having Count(*) < 2) order by a.name
/*
name val memo
---------- ----------- --------------------
a 2 a2(a的第二個值)
a 3 a3:a的第三個值
b 4 b4b4
b 5 b5b5b5b5b5
*/
--七,如果整行數據有重復,所有的列都相同。
/*

數據如下:
name val memo
a 2 a2(a的第二個值)
a 1 a1--a的第一個值
a 1 a1--a的第一個值
a 3 a3:a的第三個值
a 3 a3:a的第三個值
b 1 b1--b的第一個值
b 3 b3:b的第三個值
b 2 b2b2b2b2
b 4 b4b4
b 5 b5b5b5b5b5
*/
--在sql server 2000中只能用一個臨時表來解決,生成一個自增列,先對val取最大或最小,然后再通過自增列來取數據。
--
創建表并插入數據:
create table tb(name varchar(10),val int,memo varchar(20))
insert into tb values('a', 2, 'a2(a的第二個值)')
insert into tb values('a', 1, 'a1--a的第一個值')
insert into tb values('a', 1, 'a1--a的第一個值')
insert into tb values('a', 3, 'a3:a的第三個值')
insert into tb values('a', 3, 'a3:a的第三個值')
insert into tb values('b', 1, 'b1--b的第一個值')
insert into tb values('b', 3, 'b3:b的第三個值')
insert into tb values('b', 2, 'b2b2b2b2')
insert into tb values('b', 4, 'b4b4')
insert into tb values('b', 5, 'b5b5b5b5b5')
go

select * , px = identity(int,1,1) into tmp from tb

select m.name,m.val,m.memo from
(
select t.* from tmp t where val = (select min(val) from tmp where name = t.name)
) m
where px = (select min(px) from
(
select t.* from tmp t where val = (select min(val) from tmp where name = t.name)
) n
where n.name = m.name)

drop table tb,tmp

/*
name val memo
---------- ----------- --------------------
a 1 a1--a的第一個值
b 1 b1--b的第一個值

(2 行受影響)
*/
--在sql server 2005中可以使用row_number函數,不需要使用臨時表。
--
創建表并插入數據:
create table tb(name varchar(10),val int,memo varchar(20))
insert into tb values('a', 2, 'a2(a的第二個值)')
insert into tb values('a', 1, 'a1--a的第一個值')
insert into tb values('a', 1, 'a1--a的第一個值')
insert into tb values('a', 3, 'a3:a的第三個值')
insert into tb values('a', 3, 'a3:a的第三個值')
insert into tb values('b', 1, 'b1--b的第一個值')
insert into tb values('b', 3, 'b3:b的第三個值')
insert into tb values('b', 2, 'b2b2b2b2')
insert into tb values('b', 4, 'b4b4')
insert into tb values('b', 5, 'b5b5b5b5b5')
go

select m.name,m.val,m.memo from
(
select * , px = row_number() over(order by name , val) from tb
) m
where px = (select min(px) from
(
select * , px = row_number() over(order by name , val) from tb
) n
where n.name = m.name)

drop table tb

/*
name val memo
---------- ----------- --------------------
a 1 a1--a的第一個值
b 1 b1--b的第一個值

(2 行受影響)
*/


8.合并列值
原著:鄒建
改編:愛新覺羅.毓華(十八年風雨,守得冰山雪蓮花開)? 2007-12-16? 廣東深圳

表結構,數據如下:
id? ? value
----- ------
1? ? aa
1? ? bb
2? ? aaa
2? ? bbb
2? ? ccc

需要得到結果:
id? ? values
------ -----------
1? ? ? aa,bb
2? ? ? aaa,bbb,ccc
即:group by id, 求 value 的和(字符串相加)

1. 舊的解決方法(在sql server 2000中只能用函數解決。)
--1. 創建處理函數
create table tb(id int, value varchar(10))
insert into tb values(1, 'aa')
insert into tb values(1, 'bb')
insert into tb values(2, 'aaa')
insert into tb values(2, 'bbb')
insert into tb values(2, 'ccc')
go

CREATE FUNCTION dbo.f_str(@id int)
RETURNS varchar(8000)
AS
BEGIN
? ? DECLARE @r varchar(8000)
? ? SET @r = ''
? ? SELECT @r = @r + ',' + value FROM tb WHERE id=@id
? ? RETURN STUFF(@r, 1, 1, '')
END
GO

-- 調用函數
SELECt id, value = dbo.f_str(id) FROM tb GROUP BY id

drop table tb
drop function dbo.f_str

/*
id? ? ? ? ? value? ? ?
----------- -----------
1? ? ? ? ? aa,bb
2? ? ? ? ? aaa,bbb,ccc
(所影響的行數為 2 行)
*/

--2、另外一種函數.
create table tb(id int, value varchar(10))
insert into tb values(1, 'aa')
insert into tb values(1, 'bb')
insert into tb values(2, 'aaa')
insert into tb values(2, 'bbb')
insert into tb values(2, 'ccc')
go

--創建一個合并的函數
create function f_hb(@id int)
returns varchar(8000)
as
begin
? declare @str varchar(8000)
? set @str = ''
? select @str = @str + ',' + cast(value as varchar) from tb where id = @id
? set @str = right(@str , len(@str) - 1)
? return(@str)
End
go

--調用自定義函數得到結果:
select distinct id ,dbo.f_hb(id) as value from tb

drop table tb
drop function dbo.f_hb

/*
id? ? ? ? ? value? ? ?
----------- -----------
1? ? ? ? ? aa,bb
2? ? ? ? ? aaa,bbb,ccc
(所影響的行數為 2 行)
*/

2. 新的解決方法(在sql server 2005中用OUTER APPLY等解決。)
create table tb(id int, value varchar(10))
insert into tb values(1, 'aa')
insert into tb values(1, 'bb')
insert into tb values(2, 'aaa')
insert into tb values(2, 'bbb')
insert into tb values(2, 'ccc')
go
-- 查詢處理
SELECT * FROM(SELECT DISTINCT id FROM tb)A OUTER APPLY(
? ? ? ? SELECT [values]= STUFF(REPLACE(REPLACE(
? ? ? ? ? ? (
? ? ? ? ? ? ? ? SELECT value FROM tb N
? ? ? ? ? ? ? ? WHERE id = A.id
? ? ? ? ? ? ? ? FOR XML AUTO
? ? ? ? ? ? ), ' <N value="', ','), '"/>', ''), 1, 1, '')
)N
drop table tb

/*
id? ? ? ? ? values
----------- -----------
1? ? ? ? ? aa,bb
2? ? ? ? ? aaa,bbb,ccc

(2 行受影響)
*/

--SQL2005中的方法2
create table tb(id int, value varchar(10))
insert into tb values(1, 'aa')
insert into tb values(1, 'bb')
insert into tb values(2, 'aaa')
insert into tb values(2, 'bbb')
insert into tb values(2, 'ccc')
go

select id, [values]=stuff((select ','+[value] from tb t where id=tb.id for xml path('')), 1, 1, '')
from tb
group by id

/*
id? ? ? ? ? values
----------- --------------------
1? ? ? ? ? aa,bb
2? ? ? ? ? aaa,bbb,ccc

(2 row(s) affected)

*/

drop table tb


9.分拆列值

原著:鄒建
改編:愛新覺羅.毓華(十八年風雨,守得冰山雪蓮花開)? 2007-12-16? 廣東深圳

有表tb, 如下:
id? ? ? ? ? value
----------- -----------
1? ? ? ? ? aa,bb
2? ? ? ? ? aaa,bbb,ccc
欲按id,分拆value列, 分拆后結果如下:
id? ? ? ? ? value
----------- --------
1? ? ? ? ? aa
1? ? ? ? ? bb
2? ? ? ? ? aaa
2? ? ? ? ? bbb
2? ? ? ? ? ccc

1. 舊的解決方法(sql server 2000)
SELECT TOP 8000 id = IDENTITY(int, 1, 1) INTO # FROM syscolumns a, syscolumns b

SELECT A.id, SUBSTRING(A.[values], B.id, CHARINDEX(',', A.[values] + ',', B.id) - B.id)
FROM tb A, # B
WHERE SUBSTRING(',' + A.[values], B.id, 1) = ','

DROP TABLE #

2. 新的解決方法(sql server 2005)

create table tb(id int,value varchar(30))
insert into tb values(1,'aa,bb')
insert into tb values(2,'aaa,bbb,ccc')
go
SELECT A.id, B.value
FROM(
? ? SELECT id, [value] = CONVERT(xml,' <root> <v>' + REPLACE([value], ',', ' </v> <v>') + ' </v> </root>') FROM tb
)A
OUTER APPLY(
? ? SELECT value = N.v.value('.', 'varchar(100)') FROM A.[value].nodes('/root/v') N(v)
)B

DROP TABLE tb

/*
id? ? ? ? ? value
----------- ------------------------------
1? ? ? ? ? aa
1? ? ? ? ? bb
2? ? ? ? ? aaa
2? ? ? ? ? bbb
2? ? ? ? ? ccc

(5 行受影響)

*/


10.

/* 標題:分解字符串并查詢相關數據 作者:愛新覺羅.毓華(十八年風雨,守得冰山雪蓮花開) 時間:2008-03-18 地點:廣東深圳 說明:通過使用函數等方法分解字符串查詢相關數據。 問題:通過分解一個帶某種符號分隔的字符串在數據庫中查找相關數據。 例如 @str = '1,2,3',查詢下表得到記錄1,4,5,6 ID TypeID 1 1,2,3,4,5,6,7,8,9,10,11,12 2 2,3 3 3,7,8,9 4 2,6 5 4,5 6 6,7 */ ----------------------------- create table tb (ID int , TypeID varchar(30)) insert into tb values(1 , '1,2,3,4,5,6,7,8,9,10,11,12') insert into tb values(2 , '2,3') insert into tb values(3 , '3,7,8,9') insert into tb values(4 , '2,6') insert into tb values(5 , '4,5') insert into tb values(6 , '6,7') go ----------------------------- --如果僅僅是一個,如@str = '1'. declare @str as varchar(30) set @str = '1' select * from tb where charindex(',' + @str + ',' , ',' + TypeID + ',') > 0 select * from tb where ',' + TypeID + ',' like '%,' + @str + ',%' /* ID TypeID ----------- ------------------------------ 1 1,2,3,4,5,6,7,8,9,10,11,12 (所影響的行數為 1 行) */ ----------------------------- --如果包含兩個,如@str = '1,2'. declare @str as varchar(30) set @str = '1,2' select * from tb where charindex(',' + left(@str , charindex(',' , @str) - 1) + ',' , ',' + typeid + ',') > 0 or charindex(',' + substring(@str , charindex(',' , @str) + 1 , len(@str)) + ',' , ',' + typeid + ',') > 0 select * from tb where ',' + typeid + ',' like '%,' + left(@str , charindex(',' , @str) - 1) + ',%' or ',' + typeid + ',' like '%,' + substring(@str , charindex(',' , @str) + 1 , len(@str)) + ',%' /* ID TypeID ----------- ------------------------------ 1 1,2,3,4,5,6,7,8,9,10,11,12 2 2,3 4 2,6 (所影響的行數為 3 行) */ ------------------------------------------- --如果包含三個或四個,用PARSENAME函數來處理. declare @str as varchar(30) set @str = '1,2,3,4' select * from tb where charindex(',' + parsename(replace(@str , ',' , '.') , 4) + ',' , ',' + typeid + ',') > 0 or charindex(',' + parsename(replace(@str , ',' , '.') , 3) + ',' , ',' + typeid + ',') > 0 or charindex(',' + parsename(replace(@str , ',' , '.') , 2) + ',' , ',' + typeid + ',') > 0 or charindex(',' + parsename(replace(@str , ',' , '.') , 1) + ',' , ',' + typeid + ',') > 0 select * from tb where ',' + typeid + ',' like '%,' + parsename(replace(@str , ',' , '.') , 4) + ',%' or ',' + typeid + ',' like '%,' + parsename(replace(@str , ',' , '.') , 3) + ',%' or ',' + typeid + ',' like '%,' + parsename(replace(@str , ',' , '.') , 2) + ',%' or ',' + typeid + ',' like '%,' + parsename(replace(@str , ',' , '.') , 1) + ',%' /* ID TypeID ----------- ------------------------------ 1 1,2,3,4,5,6,7,8,9,10,11,12 2 2,3 3 3,7,8,9 4 2,6 5 4,5 (所影響的行數為 5 行) */ --------------------------------------- --如果超過四個,則只能使用函數或動態SQL來分解并查詢數據。 /* 名稱:fn_split函數. 功能:實現字符串分隔功能的函數 */ create function dbo.fn_split(@inputstr varchar(8000), @seprator varchar(10)) returns @temp table (a varchar(200)) as begin declare @i int set @inputstr = rtrim(ltrim(@inputstr)) set @i = charindex(@seprator , @inputstr) while @i >= 1 begin insert @temp values(left(@inputstr , @i - 1)) set @inputstr = substring(@inputstr , @i + 1 , len(@inputstr) - @i) set @i = charindex(@seprator , @inputstr) end if @inputstr <> '\' insert @temp values(@inputstr) return end go --調用 declare @str as varchar(30) set @str = '1,2,3,4,5' select distinct m.* from tb m, (select * from dbo.fn_split(@str,',')) n where charindex(',' + n.a + ',' , ',' + m.typeid + ',') > 0 drop table tb drop function dbo.fn_split /* ID TypeID ----------- ------------------------------ 1 1,2,3,4,5,6,7,8,9,10,11,12 2 2,3 3 3,7,8,9 4 2,6 5 4,5 (所影響的行數為 5 行) */ ------------------------------------------ --使用動態SQL的語句。 declare @str varchar(200) declare @sql as varchar(1000) set @str = '1,2,3,4,5' set @sql = 'select ''' + replace(@str , ',' , ''' as id union all select ''') set @sql = @sql + '''' set @sql = 'select distinct a.* from tb a , (' + @sql + ') b where charindex(' + ''','' + b.id + ' + ''',''' + ' , ' + ''','' + a.typeid + ' + ''',''' + ') > 0 ' exec (@sql) /* ID TypeID ----------- ------------------------------ 1 1,2,3,4,5,6,7,8,9,10,11,12 2 2,3 3 3,7,8,9 4 2,6 5 4,5 (所影響的行數為 5 行) */

?


11.

/* 本文由微軟新聞組摘錄下來的。一段非常有用的腳本。 如果碰到日志文件過大的問題,用SHIRNK DATABASE, TRUNCATE LOG FILE不是很有效時,可以考慮試下下面的腳本。把代碼COPY到查詢分析器里,然后修改其中的3個參數(數據庫名,日志文件名,和目標日志文件的大小),運行即可 */ ---------------------------------------------------------------------------------- SET NOCOUNT ON DECLARE @LogicalFileName sysname, --日志文件名 @MaxMinutes INT, --允許此腳本執行的最長時間 @NewSize INT --目標日志文件的大小 USE CRM -- 要操作的數據庫名 SELECT @LogicalFileName = 'CRM_LOG', -- 日志文件名 @MaxMinutes = 10, -- Limit on time allowed to wrap log. @NewSize = 1 -- 想要收縮到的目標大小(單位M),此處標記收縮到1M 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 ----------------------------------------------------------------------------


?

12.

--遞歸刪除父節點及所有子節點
create table tb(Id int, ParentId int, Name varchar(5))
insert into tb select 1, 0, 'a1'
union all select 2,2, 'a2'
union all select 14, 1, 'b11'
union all select 15, 1, 'b12'
union all select 16, 14, 'c13'
union all select 17, 14, 'c14'
union all select 104,17,'d15'
go
WITH temptab(id, parentid, name) AS
(
SELECT root.id, root.parentid, root.name
FROM tb root
WHERE id=1
UNION ALL
SELECT sub.id, sub.parentid, sub.name
FROM tb sub, temptab super
WHERE sub.parentid = super.id
)
delete from tb where id in(
select id from temptab
)
select * from tb
go
drop table tb
/*
Id ParentId Name
----------- ----------- -----
2 2 a2

14.
精妙SQL語句

明:復制表(只復制結構,源表名:a 新表名:b)
SQL: select * into b from a where 1 <>1

說明:拷貝表(拷貝數據,源表名:a 目標表名:b)
SQL: insert into b(a, b, c) select d,e,f from b;

說明:顯示文章、提交人和最后回復時間
SQL: select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b

說明:外連接查詢(表名1:a 表名2:b)
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

說明:日程安排提前五分鐘提醒
SQL: select * from 日程安排 where datediff( <|>minute <|>,f開始時間,getdate())>5


說明:兩張關聯表,刪除主表中已經在副表中沒有的信息
SQL:
delete from info where not exists ( select * from infobz where info.infid=infobz.infid )

說明:--
SQL:
SELECT A.NUM, A.NAME, B.UPD_DATE, B.PREV_UPD_DATE
FROM TABLE1,
(SELECT X.NUM, X.UPD_DATE, Y.UPD_DATE PREV_UPD_DATE
FROM (SELECT NUM, UPD_DATE, INBOUND_QTY, STOCK_ONHAND
FROM TABLE2
WHERE TO_CHAR(UPD_DATE, <|>YYYY/MM <|>) = TO_CHAR(SYSDATE, <|>YYYY/MM <|>)) X,
(SELECT NUM, UPD_DATE, STOCK_ONHAND
FROM TABLE2
WHERE TO_CHAR(UPD_DATE, <|>YYYY/MM <|>) =

TO_CHAR(TO_DATE(TO_CHAR(SYSDATE, <|>YYYY/MM <|>) ||
<|>/01 <|>, <|>YYYY/MM/DD <|>) - 1,
<|>YYYY/MM <|>) ) Y,
WHERE X.NUM = Y.NUM (+)
AND X.INBOUND_QTY + NVL(Y.STOCK_ONHAND,0) <> X.STOCK_ONHAND ) B
WHERE A.NUM = B.NUM

說明:--
SQL:

select * from studentinfo where not exists(select * from student where
studentinfo.id=student.id) and 系名稱=
<|>"&strdepartmentname&" <|> and 專業名稱=
<|>"&strprofessionname&" <|> order by 性別,生源地,高考總成績

說明:
從數據庫中去一年的各單位電話費統計(電話費定額賀電化肥清單兩個表來源)
SQL:
SELECT a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, <|>yyyy <|>) AS telyear,
SUM(decode(TO_CHAR(a.telfeedate, <|>mm <|>), <|>01 <|>, a.factration)) AS JAN,
SUM(decode(TO_CHAR(a.telfeedate, <|>mm <|>), <|>02 <|>, a.factration)) AS FRI,
SUM(decode(TO_CHAR(a.telfeedate, <|>mm <|>), <|>03 <|>, a.factration)) AS MAR,
SUM(decode(TO_CHAR(a.telfeedate, <|>mm <|>), <|>04 <|>, a.factration)) AS APR,
SUM(decode(TO_CHAR(a.telfeedate, <|>mm <|>), <|>05 <|>, a.factration)) AS MAY,
SUM(decode(TO_CHAR(a.telfeedate, <|>mm <|>), <|>06 <|>, a.factration)) AS JUE,
SUM(decode(TO_CHAR(a.telfeedate, <|>mm <|>), <|>07 <|>, a.factration)) AS JUL,
SUM(decode(TO_CHAR(a.telfeedate, <|>mm <|>), <|>08 <|>, a.factration)) AS AGU,
SUM(decode(TO_CHAR(a.telfeedate, <|>mm <|>), <|>09 <|>, a.factration)) AS SEP,
SUM(decode(TO_CHAR(a.telfeedate, <|>mm <|>), <|>10 <|>, a.factration)) AS OCT,
SUM(decode(TO_CHAR(a.telfeedate, <|>mm <|>), <|>11 <|>, a.factration)) AS NOV,
SUM(decode(TO_CHAR(a.telfeedate, <|>mm <|>), <|>12 <|>, a.factration)) AS DEC
FROM (SELECT a.userper, a.tel, a.standfee, b.telfeedate, b.factration
FROM TELFEESTAND a, TELFEE b
WHERE a.tel = b.telfax) a
GROUP BY a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, <|>yyyy <|>)

說明:四表聯查問題:
SQL: 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 .....

說明:得到表中最小的未使用的ID號
SQL:
SELECT (CASE WHEN EXISTS(SELECT * FROM Handle b WHERE b.HandleID = 1) THEN MIN(HandleID) + 1 ELSE 1 END) as HandleID
FROM Handle
WHERE NOT HandleID IN (SELECT a.HandleID - 1 FROM Handle a)


15.ip各段內容提取,類似有3或4段字串通過一特殊字符連接的字串提取
-----------------------------------
declare @a varchar(50)
set @a='192.168.1.123'
SELECT PARSENAME(@a,1),PARSENAME(@a,2),PARSENAME(@a,3),PARSENAME(@a,4)
set @a='100,200,300'
SELECT PARSENAME(replace(@a,',','.'),1)高,PARSENAME(replace(@a,',','.'),2)寬
,PARSENAME(replace(@a,',','.'),3)長

16.--備份
declare? @sql? varchar(8000)?
set? @sql='backup? database? mis? ? to? disk=''d:\databack\mis\mis'?
+rtrim(convert(varchar,getdate(),112))+'.bak'''?
exec(@sql)? ?
--刪除15天前備份文件?
set? @sql='del? d:\databack\mis\mis'?
+rtrim(convert(varchar,getdate()-15,112))+'.bak'''?
exec? master..xp_cmdshell? @sql

17.判斷sql執行所花的時間(精度為毫秒)

DECLARE @begin datetime
DECLARE @chaju bigint
DECLARE @end datetime
SET @begin=getdate()

要執行的sql語句......

SET @end=getdate()? ? ?
SELECT @chaju = datediff(Millisecond, @begin, @end)
PRINT @chaju?

18.USE MASTER--連接系統數據庫
IF EXISTS(select 1 from master..sysdatabases where name='bankDB')
DROP DATABASE bankDB
GO
-----------------------------------------------建庫------------------
--打開外圍服務器
EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
GO
RECONFIGURE
GO
--新建文件夾
exec xp_cmdshell 'MD e:\數據庫'

CREATE DATABASE bankDB
ON
(
NAME ='bankDB',
FILENAME='e:\數據庫\bankDB.mdf',
SIZE = 10,
MAXSIZE=500,
FILEGROWTH=15%
)
GO
--------------------------------------------------建表-----------------
USE bankDB
--用戶信息表
IF EXISTS(select 1 from bankDB..sysobjects where name='userInfo')
DROP TABLE userInfo
GO
CREATE TABLE userInfo
(
customerID int identity(1,1) PRIMARY KEY , --顧客編號(自動增長 主鍵)
customerName varchar(20) not null, --開戶名
PID varchar(20)UNIQUE not null, --身份證(18-15位數 唯一約束)
telephone varchar(20) not null, --聯系電話(****-********或手機號11位數)
[address] ntext --聯系地址
)
--銀行卡信息表
IF EXISTS(select 1 from bankDB..sysobjects where name='cardInfo')
DROP TABLE cardInfo
GO
CREATE TABLE cardInfo
(
cardID varchar(20) primary key , --卡號? (格式為1010 3576 **** ***(*部分是隨機產生))
curType varchar(10) default('RMB') not null,--貨幣種類 (默認為RMB)
savingType varchar(10), --存款類型 (活期/定活兩便/定期)
openDate datetime default(getdate()) not null,--開戶日期 (默認為當前時間)
openMoney money check(openMoney <1) not null, --開戶金額 (不能低于1元)
dalance money check(dalance <1) not null, --余額 (不能低于1元 否則將銷戶)
pass varchar(20) default(888888) not null,--密碼 (6位數 開戶時默認為6個8)
IsReportLoss bit default(0) not null, --是否過失 (是/否 默認為否 1是 0否)
customerID int not null --顧客編號 (外鍵 該卡號對應的顧客編號 一個用戶可辦多張卡)
)
--交易信息表
IF EXISTS(select 1 from bankDB..sysobjects where name='transInfo')
DROP TABLE transInfo
GO
CREATE TABLE transInfo
(
transDate datetime not null, --交易日期(默認為當前時間)
cardID varchar(20) not null, --卡號(外鍵 可重復索引)
transType varchar(10) not null, --交易類型(只能是存入/支取)
transMoney money check(transMoney>0) not null, --交易金額(大于0)
remark ntext --備注(其它說明)
)
------------------------------約束-------------------------------
--約束電話和手機號碼
if(object_id('uq_pid') is not null)
begin
alter table userinfo
drop constraint uq_pid
end
if(object_id('ck_PID') is not null)
begin
alter table userinfo
drop constraint ck_PID
end
if(object_id('ck_telephone') is not null)
begin
alter table userinfo
drop constraint ck_telephone
end
alter table userInfo
add constraint ck_PID check(len(pid) in (15,18)),
constraint uq_PID unique(pid),
constraint ck_telephone check(telephone like '1[35][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'--約束手機號碼
or
telephone like '[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'--010-12345678
or
telephone like '[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'--0719-12345678
or
telephone like '[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9][0-9]')--0719-1234567


----------------------------------------------設置卡號為隨機數(方法1)---------------------------
declare @r decimal(10,8)
declare @time varchar(25)
set @time=convert(varchar,getdate(),120)+convert(varchar,datepart(ms,getdate()))
set @time=replace(@time,' ','')
set @time=replace(@time,':','')
set @time=replace(@time,'-','')

set @time=substring(@time,8,len(@time)-1)
--select @time--查看獲得的隨機數

select @r=rand(convert(bigint,@time))
set @time=cast(@r as varchar)
--select @time
set @time=substring(@time,3,len(@time)-1)
print @time
print '1001'+convert(varchar(10),@time)

----------------------------------------------設置卡號為隨機數(方法2用了 存儲過程)---------------------------
create proc proc_randCardID
@cardid varchar(19) output
as
declare @r numeric(8,8)
set @cardid='1010 3657 '
while(1=1)
begin
set @r=rand(datepart(mm,getdate())*100000+datepart(ss,getdate())*1000+datepart(ms,getdate()))
declare @temp char(8)
set @temp=substring(convert(varchar,@r),3,8)
set @cardid=@cardid+substring(@temp,1,4)+' '+substring(@temp,5,4)
if not exists(select 1 from cardinfo where cardid=@cardid)
break
end
--測試(調用存儲過程)
declare @card varchar(19)
exec proc_randCardID @card output
print @card
*/

19./*通用分頁存儲過程*/
USE HotelManagementSystem
GO
IF EXISTS(SELECT * FROM sys.objects WHERE NAME='up_GetPageOfRecords')
DROP PROCEDURE up_GetPageOfRecords
GO
--創建存儲過程
CREATE PROCEDURE up_GetPageOfRecords
@pageSize int = 20,? ? ? ? ? ? ? ? ? ? ? ? --分頁大小
@currentPage int ,? ? ? ? ? ? ? ? ? ? ? ? --第幾頁
@columns varchar(1000) = '*',? ? ? ? ? ? ? --需要得到的字段
@tableName varchar(100),? ? ? ? ? ? ? ? ? --需要查詢的表?
@condition varchar(1000) = '',? ? ? ? ? ? --查詢條件, 不用加where關鍵字
@ascColumn varchar(100) = '',? ? ? ? ? ? ? --排序的字段名 (即 order by column asc/desc)
@bitOrderType bit = 0,? ? ? ? ? ? ? ? ? ? --排序的類型 (0為升序,1為降序)
@pkColumn varchar(50) = ''? ? ? ? ? ? ? ? --主鍵名稱

AS
BEGIN? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? --存儲過程開始
DECLARE @strTemp varchar(300)
DECLARE @strSql varchar(5000)? ? ? ? ? ? ? --該存儲過程最后執行的語句
DECLARE @strOrderType varchar(1000)? ? ? ? --排序類型語句 (order by column asc或者order by column desc)

BEGIN
IF @bitOrderType = 1 ? ? --降序
BEGIN
SET @strOrderType = ' ORDER BY '+@ascColumn+' DESC'
SET @strTemp = ' <(SELECT min'
END
ELSE --升序
BEGIN
SET @strOrderType = ' ORDER BY '+@ascColumn+' ASC'
SET @strTemp = '>(SELECT max'
END

IF @currentPage = 1 --第一頁
BEGIN
IF @condition != ''
SET @strSql = 'SELECT TOP '+STR(@pageSize)+' '+@columns+' FROM '+@tableName+
' WHERE '+@condition+@strOrderType
ELSE
SET @strSql = 'SELECT TOP '+STR(@pageSize)+' '+@columns+' FROM '+@tableName+@strOrderType
END

ELSE -- 其他頁
BEGIN
IF @condition !=''
SET @strSql = 'SELECT TOP '+STR(@pageSize)+' '+@columns+' FROM '+@tableName+
' WHERE '+@condition+' AND '+@pkColumn+@strTemp+'('+@pkColumn+')'+' FROM (SELECT TOP '+STR((@currentPage-1)*@pageSize)+
' '+@pkColumn+' FROM '+@tableName+@strOrderType+') AS TabTemp)'+@strOrderType
ELSE
SET @strSql = 'SELECT TOP '+STR(@pageSize)+' '+@columns+' FROM '+@tableName+
' WHERE '+@pkColumn+@strTemp+'('+@pkColumn+')'+' FROM (SELECT TOP '+STR((@currentPage-1)*@pageSize)+' '+@pkColumn+
' FROM '+@tableName+@strOrderType+') AS TabTemp)'+@strOrderType
END

END
EXEC (@strSql)
END

20.雙色球和值選球
Create proc up_getSumball
@XmlString varchar(2000),
@Max int
as
begin
declare @idtb table(id int)
? ? create table #tb? (id int,num int)
declare @num int,@id int,@sum int,@times int
? ? declare @idHandle int
set @sum=0
set @times=0

? ? EXEC sp_xml_preparedocument @idHandle OUTPUT, @XmlString
insert into? #tb(id,num)
select * from openxml(@idHandle,N'/root/tb_ball')
with #tb

while (@sum <>@max or @times <>6)
begin
select top 1 @id=id,@num=num from #tb where num <=33 order by newid()
if @num <>@max begin
if not exists(select 1 from @idtb where id=@id)
insert into @idtb select @id
end
select @sum=sum(num) from #tb where id in(select id from @idtb)
select @times=count(1) from @idtb
if (@times>6 ) begin
delete @idtb
end
? ? ? ? if ((@Max=@num) and (@times <6)) begin
delete @idtb
? ? ? ? end
? ? ? ?
select @times=count(1) from @idtb
end

select * from #tb where id in(select id from @idtb)
? ? drop table #tb
end

go


declare @tb table(id int,num int)
insert into @tb select 1,1
insert into @tb select 2,2
insert into @tb select 3,3
insert into @tb select 4,4
insert into @tb select 5,5
insert into @tb select 6,6
insert into @tb select 7,7
insert into @tb select 8,8
insert into @tb select 9,9
insert into @tb select 11,11
insert into @tb select 12,12
insert into @tb select 13,13
insert into @tb select 14,14
insert into @tb select 15,15
insert into @tb select 16,16
insert into @tb select 17,17
insert into @tb select 18,18
insert into @tb select 19,19
insert into @tb select 20,20
insert into @tb select 21,21
insert into @tb select 22,22
insert into @tb select 23,23
insert into @tb select 24,24
insert into @tb select 25,25
insert into @tb select 26,26
insert into @tb select 27,27
insert into @tb select 28,28
insert into @tb select 29,29
insert into @tb select 30,30
insert into @tb select 31,31
insert into @tb select 32,32
insert into @tb select 33,33
declare @dataxml xml
declare @strXml varchar(2000)
set @dataxml=(select * from @tb as tb_ball? for xml auto,root('root'))
set @strXml=convert(varchar(2000),@dataxml)
exec up_getSumball @strXml,50

21.根據身份證計算性別函數(原創)

SQL code

CREATE FUNCTION [dbo].[sex]
(
@IDCardNo NVARCHAR(50)
)
RETURNS int
AS
BEGIN
DECLARE @sex int

if (LEN(@IDCardNo)=18 and ISNUMERIC(SUBSTRING(@IDCardNo,17,1))=1 )
SET @sex= (
case
when SUBSTRING(@IDCardNo,17,1) in(1,3,5,7,9) then 1
when SUBSTRING(@IDCardNo,17,1) in(2,4,6,7,0) then 2
else
0
end
)

else if (LEN(@IDCardNo)=15 and ISNUMERIC(SUBSTRING(@IDCardNo,15,1))=1 )
SET @sex= (
case
when SUBSTRING(@IDCardNo,15,1) in(1,3,5,7,9) then 1
when SUBSTRING(@IDCardNo,15,1) in(2,4,6,7,0) then 2
else
0
end
)

else
SET @sex=0
RETURN(@sex)
END

22.--下面的SQL語句可以直接更改一個表的所有者,前提是要testuser用戶存在
--
EXEC sp_changeobjectowner 'dob.product', 'testuser'



----下面是通過修改系統表的相應值來達到修改所有者的目的。在sql2000下可用。在2005下還沒有測試。
--
--創建存儲過程

--更改單個表的所有者
if exists ( select name from sysobjects where name = 'ChangeTableOwner' and type= 'P')
drop procedure ChangeTableOwner
go

create procedure ChangeTableOwner
@TableName varchar(50),
@newUserName varchar(50)
as

Begin
exec sp_configure 'allow updates', 1
RECONFIGURE WITH OVERRIDE

declare @newId int

if exists (select uid from sysusers where name = @newUserName)
BEGIN
select @newId = uid from sysusers where name = @newUserName
update sysobjects set uid = @newId where name=@TableName and type='u'
END
else
BEGIN
print N'the @newUserName does not exist,please check it and try again!'
END
exec sp_configure 'allow updates', 0
RECONFIGURE WITH OVERRIDE
End
go

--更改所有表的所有者(不會更改系統表)
if exists ( select name from sysobjects where name = 'ChangeUser' and type= 'P')
drop procedure ChangeUser
go

create procedure ChangeUser
@newUserName varchar(50)
as

Begin
sp_configure
'allow updates', 1
RECONFIGURE WITH OVERRIDE

declare @newId int

if exists (select uid from sysusers where name = @newUserName)
BEGIN
select @newId = uid from sysusers where name = @newUserName
update sysobjects set uid = @newId where type='u'
END
else
BEGIN
print N'the @newUserName does not exist,please check it and try again!'
END
sp_configure
'allow updates', 0
RECONFIGURE WITH OVERRIDE
End


23.use master
go
if exists(select * from sysdatabases where name = 'stuDB')
drop database stuDB
create database stuDB
on
(
name = 'stuDB_data', --主數據文件名
filename = 'E:\stuDB_data.mdf', --主數據文件的物理名稱
size = 5mb, --主數據文件的初始大小
maxsize = 10mb, --主數據文件的最大值
filegrowth = 15% --主數據文件的增長值
)
log on
(
name = 'stuDB_log', --日志文件名
filename = 'E:\stuDB_log.ldf', --日志文件的物理名稱
size = 2mb, --日志文件的初始大小
filegrowth = 15% --日志文件的增長率
)
go

/*--創建學生信息表stuInfo--*/
use stuDB --設置當前數據庫為stuDB數據庫,以便在stuDB中創建表
go
create table stuInfo /*--創建學員信息表--*/
(
stuName nvarchar(20) not null, --學生姓名,非空
stuNo nchar(6) not null, --學生學號,非空
stuSex nchar(1) not null, --學生性別
stuAge int not null, --學生年齡
stuSeat int identity(1,1), --座位編號
stuAddress text --學生地址
)
go
/*--為stuInfo表添加約束條件--*/
--添加主鍵約束,學號作為主鍵
alter table stuInfo
add constraint pk_stuNo primary key(stuNo)
--添加檢查約束,要求學號必須是"s253**"
alter table stuInfo
add constraint ck_stuNo check(stuNo like 's253__')
--添加檢查約束,要求性別必須是男或女
alter table stuInfo
add constraint ck_stuSex check(stuSex = '男' or stuSex = '女')
--添加檢查約束,要求年齡必須在15~40歲之間
alter table stuInfo
add constraint ck_stuAge check(stuAge between 15 and 40)
--添加檢查約束,要求座位號必須在1~30之間
alter table stuInfo
add constraint ck_stuSeat check(stuSeat <= 30)
--添加默認約束,如果地址不填就默認為"地址不詳"
alter table stuInfo
add constraint df_stuAddress default('地址不詳') for stuAddress
go
/*--向學生信息表中(stuInfo)插入數據--*/
insert into stuInfo values('張秋麗','s25301','男',18,default)
insert into stuInfo
select '李斯文','s25303','女',22,'荷蘭洛陽' union
select '李文才','s25302','男',31,'北京海淀' union
select '歐陽俊雄','s25304','男',28,'新建威武哈' union
select '果凍','s25305','男',25,'成都錦江區'
/*--創建學員成績表(stuMarks)--*/
create table stuMarks
(
examNO nchar(7) not null, --考號
stuNo nchar(6) not null, --學號
writtenExam int not null, --筆試成績
labExam int not null --機試成績
)
go
/*--向學員成績表(stuMarks)中插入信息--*/
insert stuMarks
select 's2007','s25301',80,58 union
select 's2008','s25303',50,90 union
select 's2009','s25302',65,0 union
select 's2010','s25304',77,82
select * from stuMarks
select * from stuInfo
set nocount on
/*--創建儲存過程--*/
if exists(select * from sysobjects where name = 'proc_stu')
drop proc proc_stu
go
create proc proc_stu
@writtenExam int = 60,
@labExam int = 60
as
select stuInfo.stuName as 姓名,stuInfo.stuNo as 學號
,[筆試成績] = case
when stuMarks.writtenExam is null then '缺考'
else convert(nvarchar(3),writtenExam)
? end
,[機試成績] = case
when stuMarks.labExam is null then '缺考'
else convert(nvarchar(3),labExam)
? end
,[是否通過] = case
when stuMarks.labExam >= @labExam and stuMarks.writtenExam >= @writtenExam then '是'
else '否'
? end
from stuInfo left join stuMarks on stuInfo.stuNo = stuMarks.stuNo
go
exec proc_stu
/*--創建帶三個參數的儲存過程--*/
if exists(select * from sysobjects where name = 'proc_stu2')
drop proc proc_stu2
go
create proc proc_stu2
@noPass int output,
@writtenExam int = 60,
@labExam int = 60
as
select @noPass = count(*)
from(select stuInfo.stuName as 姓名,stuInfo.stuNo as 學號
,[筆試成績] = case
when stuMarks.writtenExam is null then '缺考'
else convert(nvarchar(3),writtenExam)
? end
,[機試成績] = case
when stuMarks.labExam is null then '缺考'
else convert(nvarchar(3),labExam)
? end
,[是否通過] = case
when stuMarks.labExam >= @labExam and stuMarks.writtenExam >= @writtenExam then '是'
else '否'
? end
from stuInfo left join stuMarks on stuInfo.stuNo = stuMarks.stuNo) as temp where temp.[是否通過] = '否'
go
declare @noPass int
exec proc_stu2 @noPass output,60,60
print '沒有通過的人數為' + convert(nvarchar(2),@noPass) + '人'
/*--創建統計沒有通過的學員信息的儲存過程--*/
if exists(select * from sysobjects where name = 'proc_stu3')
drop proc proc_stu3
go
create proc proc_stu3
@writtenExam int = 60,
@labExam int = 60
as
declare @IsPass int
declare @sum int
declare @noPass int
declare @noPass1 int
select 筆試及格線 = @writtenExam,機試及格線 = @labExam
--查詢沒有通過考試的學員信息
select *
from(select stuInfo.stuName as 姓名,stuInfo.stuNo as 學號
,[筆試成績] = case
when stuMarks.writtenExam is null then '缺考'
else convert(nvarchar(3),writtenExam)
? end
,[機試成績] = case
when stuMarks.labExam is null then '缺考'
else convert(nvarchar(3),labExam)
? end
,[是否通過] = case
when stuMarks.labExam >= @labExam and stuMarks.writtenExam >= @writtenExam then '是'
else '否'
? end
from stuInfo left join stuMarks on stuInfo.stuNo = stuMarks.stuNo) as temp where temp.[是否通過] = '否'
--統計通過的人數
select @IsPass = count(*)
from(select stuInfo.stuName as 姓名,stuInfo.stuNo as 學號
,[筆試成績] = case
when stuMarks.writtenExam is null then '缺考'
else convert(nvarchar(3),writtenExam)
? end
,[機試成績] = case
when stuMarks.labExam is null then '缺考'
else convert(nvarchar(3),labExam)
? end
,[是否通過] = case
when stuMarks.labExam >= @labExam and stuMarks.writtenExam >= @writtenExam then '是'
else '否'
? end
from stuInfo left join stuMarks on stuInfo.stuNo = stuMarks.stuNo) as temp where temp.[是否通過] = '是'
select @sum = count(*) from stuInfo
set @noPass = @sum - @IsPass
set @noPass1 = @noPass * 100/@sum
if @noPass1 > 60
select 未通過人數 = @noPass,結論 = '超過60%及格分數還應下調'
else
select 未通過人數 = @noPass
go

exec proc_stu3 50,50


24.在前人基礎上修改過的分頁存儲過程,單表多表都行,性能經過千萬級數據驗證

CREATE? ? ? ? ? ? ? ? ? procedure [dbo].[userpage]
(
@SqlWhere varchar(1000)='',? --查詢條件, 可為空
@pagenum int=20,? ? ? ? ? ? ? --每頁的記錄數
@beginline int=1,? ? ? ? ? ? --第幾頁,默認第一頁
@SqlTable varchar(1000),? ? ? --要查詢的表或視圖,也可以一句sql語句
@SqlColumn varchar(1000),? ? --查詢的字段
@SqlPK varchar(50),? ? ? ? ? --主鍵 必須填寫,自動編號字段
@SqlOrder varchar(200)? ,? ? --排序,可為空,則默認為以主鍵倒序排列
@GetCount bit=0,? ? ? ? ? ? ? --0為取查詢結果,1為取查詢總數
@totalCount int? ? ? ? ? ? ? --0為不限制結果總數,大于0即為取@totalCount條數據,其他忽視
)
as
set nocount on
declare @PageLowerBound int
declare @PageUpperBound int
declare @sqlstr nvarchar(2000)
declare @d datetime
if @SqlWhere=''
? begin
? set @SqlWhere=' where 1=1 '
? end
else
? begin
? set @SqlWhere=' where 1=1 and '+@SqlWhere+' '
? end
if @SqlOrder=''
? begin
? set @SqlOrder=' order by '+@SqlPK+' desc'
? end
else
? begin
? set @SqlOrder=' order by '+@SqlOrder
? end
if @SqlColumn='' set @SqlColumn=' * '
if @beginline=0 set @beginline=1
if @totalcount>0
begin
declare @totalpage int
set @totalpage=@totalcount/@pagenum
if @totalcount%@pagenum >0 set @totalpage=@totalpage+1
if @beginline>@totalpage set @beginline=@totalpage
end

declare @mytop nvarchar(20)
set @mytop=''
if @totalcount>0 set @mytop=' top '+convert(nvarchar(10),@totalcount)+' '
IF @GetCount=1
BEGIN
declare @Count int
declare @sCount int
if @totalCount=0
begin
set @sqlstr=N'select @sCount=count(1) FROM '+@SqlTable+@SqlWhere
end
else
begin
set @sqlstr=N'select @sCount=count(1) FROM '+@SqlTable+' where '+@SqlPK+' in (select top '+convert(nvarchar(10),@totalcount)+' '+@SqlPK+' from '+@SqlTable+' '+@Sqlwhere+')'
end

Exec sp_executesql @sqlstr,N'@sCount int outPut',@Count output
select @count as totalCount
END
else
begin
if @beginline=1
begin
set @sqlstr='select? '+@SqlColumn+' from '+@SqlTable+' where '+@sqlPK+' in (select top '+str(@pagenum)+' '+@SqlPK+' from '+@SqlTable+@SqlWhere+@SqlOrder+')'+@SqlOrder
Exec sp_executesql @sqlstr
set nocount off
end
else
begin
set @PageLowerBound=(@beginline-1)*@pagenum
set @PageUpperBound=@PageLowerBound+@pagenum


create table #pageindex(temporary_id int identity(1,1) not null,temporary_nid int)
create unique clustered index index_nid_pageindex on #pageindex(temporary_id)
set rowcount @PageUpperBound
set @sqlstr=N'insert into #pageindex(temporary_nid) select '+@mytop+@SqlPK+' from '+@SqlTable+@SqlWhere+@SqlOrder
Exec sp_executesql @sqlstr
set @sqlstr='select '+@SqlColumn+' FROM '+ @SqlTable +' inner join #pageindex p on '+@SqlPK+'=p.temporary_nid and (p.temporary_id>'+STR(@PageLowerBound)+') and (p.temporary_id <='+STR(@PageUpperBound)+')' +@SqlOrder
Exec sp_executesql @sqlstr
set nocount off
drop table #pageindex
end
end

GO


25.--MS? SQLSERVER? 清空所有表的數據?
? CREATE PROC P_DelAllUserTableData?
? as?
? Begin?
? declare? @name? varchar(20)?
? Declare? Cur? Cursor? For? ?
? ? ? ? ? ? select? Name? from? sysobjects? where? xtype='u'? and? status>=0? and? Name? like? '%WQ_%'?
? declare? @SQL? Varchar(20)?
? Open? Cur? ?
? Fetch? Cur? Into? @name?
? While? @@FETCH_STATUS=0?
? ? BEGIN?
? ? ? ? Set? @sql='DELETE? '+@name+''?
? ? ? ? Exec(@sql)?
? ? ? ? Fetch? Cur? Into? @name?
? ? End?
? Close? Cur?
? Deallocate? cur?
? End?
? GO? ?
? exec? P_DelAllUserTableData?

轉載于:https://www.cnblogs.com/tonybinlj/archive/2009/04/17/1437906.html

總結

以上是生活随笔為你收集整理的SQL學習的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。