【转】T-SQL 教程
1 USE [test]
2 GO
3 /****** Object: StoredProcedure [dbo].[PageIndex] Script Date: 12/07/2011 10:26:36 ******/
4 SET ANSI_NULLS ON
5 GO
6 SET QUOTED_IDENTIFIER ON
7 GO
8 ALTER PROCEDURE [dbo].[PageIndex]
9 (
10 @Tbname varchar(100),--表名字
11 @Strfield varchar(100),--查询字段
12 @idfield varchar(50),--主键ID
13 @Toppage int=10,--每页行数
14 @PageNow int=0,--查询页数
15 @strWhere varchar(100) ='1=1',--查询条件
16 @Pagecount int=0 output,--总页数
17 @order varchar(200)=''--排序条件
18 )
19 AS
20 DECLARE @sql nvarchar(1000),
21 @sqloder varchar(200)
22 BEGIN
23 if(@Pagecount=0)--总页数
24 begin
25 declare @page int
26 set @sql= 'select @Page=COUNT('+@idfield+') from '+@Tbname+ ' where '+@strWhere
27 print @sql
28 exec sp_executesql @sql,N'@Page int output',@Page output--查询总行数
29 SELECT @pageCount=CEILING((@page+0.0)/@Toppage) --计算页数
30 print @pageCount
31 end
32 if(@order!='')--排序条件
33 begin
34 set @sqloder='ORDER BY '+@order
35 end
36 else
37 begin
38 set @sqloder=''
39 end
40 if(@strWhere!='')--查询条件
41 begin
42 set @strWhere='where '+@strWhere
43 end
44 begin--执行SQL语句
45 --/*
46 set @sql='SELECT TOP '
47 +cast(@Toppage as varchar(200))+
48 ' '+@Strfield+' FROM (SELECT '+@Strfield+',ROW_NUMBER() OVER (ORDER BY '
49 +@order+') AS RowNumber
50 FROM '+@Tbname+') A WHERE RowNumber > '
51 +cast(@Toppage as varchar(200))+' * ('
52 +cast(@PageNow as varchar(200))+'-1) '+@sqloder
53 --*/
54 --print @sql
55 /*set @sql ='SELECT TOP '+cast(@Toppage as varchar(200))+' '+@Strfield+ '
56 FROM '+@Tbname+'
57 WHERE '+@idfield+' >
58 (
59 SELECT ISNULL(MAX('+@idfield+'),0)
60 FROM
61 (
62 SELECT TOP ('+cast(@Toppage as varchar(200))+'*('+cast(@PageNow as varchar(200))+'-1))
63 '+@idfield+' FROM '+@Tbname+' '+@sqloder+'
64 ) A
65 ) '+@sqloder*/
66 print (@sql)
67 exec (@sql)
68
69 end
70 END
以资料整理为目的,汇总一下自己从事于这近两年多的软件开发中常用的T-SQL,涵盖存储过程,分页,行转列、列转行,锁,全局变量,聚焦索引……
可能一说到T-SQL与PL/SQL大家可能有很多认知上的不足(本人也是迷糊了好长时间,才懂得其中内涵)
简单点理解,就是T-SQL是用于MS SQLServer中,而PL/SQl适用于Oracle中的了
首先看看全局变量
1 select APP_NAME ( ) as w --当前会话的应用程序
2 select @@ERROR --返回最后执行的 Transact-SQL 语句的错误代码(integer)(如果最后一条语句不出错,就一直是0)
3 select @@IDENTITY --返回最后插入的标识值
4 select USER_NAME() --返回用户数据库用户名
5 select @@CONNECTIONS --返回自上次SQL启动以来连接或试图连接的次数。
6 select GETDATE() --当前时间
7 select @@CPU_BUSY/100 --返回自上次启动SQL 以来 CPU 的工作时间,单位为毫秒
8 USE tempdb select @@DBTS as w --为当前数据库返回当前 timestamp 数据类型的值。这一 timestamp 值保证在数据库中是唯一的。
9 select @@IDLE as w --返回SQL自上次启动后闲置的时间,单位为毫秒
10 select @@IO_BUSY AS w --返回SQL自上次启动后用于执行输入和输出操作的时间,单位为毫秒
11 select @@LANGID AS w --返回当前所使用语言的本地语言标识符(ID)
12 select @@LANGUAGE AS w --返回当前使用的语言名
13 select @@LOCK_TIMEOUT as w --当前会话的当前锁超时设置,单位为毫秒。
14 select @@MAX_CONNECTIONS as w --返回SQL上允许的同时用户连接的最大数。返回的数不必为当前配置的数值
15 EXEC sp_configure --显示当前服务器的全局配置设置
16 select @@MAX_PRECISION as w --返回 decimal 和 numeric 数据类型所用的精度级别,即该服务器中当前设置的精度。默认最大精度38。
17 select @@OPTIONS as w --返回当前 SET 选项的信息。
18 select @@PACK_RECEIVED as w --返回SQL自启动后从网络上读取的输入数据包数目。
19 select @@PACK_SENT as w --返回SQ自上次启动后写到网络上的输出数据包数目。
20 select @@PACKET_ERRORS as w --返回自SQL启动后,在SQL连接上发生的网络数据包错误数。
21 select @@SERVERNAME as w --返回运行SQL服务器名称。
22 select @@SERVICENAME as w --返回SQL正在其下运行的注册表键名
23 select @@TIMETICKS as w --返回SQL服务器一刻度的微秒数
24 select @@TOTAL_ERRORS AS w --返回 SQL服务器自启动后,所遇到的磁盘读/写错误数。
25 select @@TOTAL_READ as w --返回 SQL服务器自启动后读取磁盘的次数。
26 select @@TOTAL_WRITE as w --返回SQL服务器自启动后写入磁盘的次数。
27 select @@TRANCOUNT as w --返回当前连接的活动事务数。
28 select @@VERSION as w --返回SQL服务器安装的日期、版本和处理器类型。
再来看看针对MSSQL的备份语句
1 --查询文件是否存在
2 CREATE TABLE #tmp ([File Exists] BIT, [File is a Directory] BIT, [Parent Directory Exists] BIT)
3 INSERT INTO #tmp ([File Exists], [File is a Directory], [Parent Directory Exists])
4 EXEC master.dbo.xp_fileexist 'D:\Test.bak'
5 SELECT * FROM #tmp
6 DROP TABLE #tmp
7
8 --完整备份数据库
9
10 BACKUP DATABASE MyBakTest TO DISK='D:\Test.bak' WITH FORMAT
11
12 --对tb表插入第一条记录
13
14 INSERT INTO tb_user(uname) VALUES('第一1次差异备份')
15
16 --第一次差异备份
17
18 BACKUP DATABASE MyBakTest TO DISK='D:\Test_One_Dif.bak' WITH FORMAT,DIFFERENTIAL
19
20 --对tb表插入第二条记录
21
22 INSERT INTO tb_user(uname) VALUES('第二3次差异备份')
23
24 --第二次差异备份
25
26 BACKUP DATABASE MyBakTest TO DISK='D:\Test_Two_Dif.bak' WITH FORMAT,DIFFERENTIAL
27
28 --OK.现在直接还原.完整备份+第二次差异备份.看看第二条记录在不在.
29
30 GO
31
32 --完整备份还原
33 RESTORE DATABASE MyBackTest2 FROM DISK='D:\Test.bak' WITH REPLACE,NORECOVERY
34
35 RESTORE DATABASE MyBackTest2 FROM DISK='D:\Test_one_Dif.bak' WITH RECOVERY
36
37 --第二次差异备份还原
38 RESTORE DATABASE MyBackTest2 FROM DISK='D:\Test_Two_Dif.bak' WITH RECOVERY
用的次数不是很多,但是每次都会让我纠结一会的行转列,列转行,有了这个示例,就可以轻松应对这类问题了:
1 --行转列
2 create table #CarLog(LogDate datetime,PathLine nvarchar(10),Amount int)
3 --drop table #CarLog
4 insert into #CarLog(LogDate,PathLine,Amount)VALUES('2011-12-24','1号线',1)
5 insert into #CarLog(LogDate,PathLine,Amount)VALUES('2011-12-25','1号线',91)
6 insert into #CarLog(LogDate,PathLine,Amount)VALUES('2011-12-26','1号线',66)
7 insert into #CarLog(LogDate,PathLine,Amount)VALUES('2011-12-24','3号线',44)
8 insert into #CarLog(LogDate,PathLine,Amount)VALUES('2011-12-24','3号线',33)
9 insert into #CarLog(LogDate,PathLine,Amount)VALUES('2011-12-24','5号线',12)
10 insert into #CarLog(LogDate,PathLine,Amount)VALUES('2011-12-24','6号线',22)
11
12 select * from #CarLog
13
14 --方法1
15 SELECT LogDate,
16 (CASE WHEN PathLine='1号线' THEN Amount ELSE 0 END)AS '1号线',
17 (CASE WHEN PathLine='2号线' THEN Amount ELSE 0 END)AS '2号线',
18 (CASE WHEN PathLine='3号线' THEN Amount ELSE 0 END)AS '3号线',
19 (CASE WHEN PathLine='4号线' THEN Amount ELSE 0 END)AS '4号线',
20 (CASE WHEN PathLine='5号线' THEN Amount ELSE 0 END)AS '5号线',
21 (CASE WHEN PathLine='6号线' THEN Amount ELSE 0 END)AS '6号线'
22 FROM #CarLog
23 Group By PathLine,LogDate,Amount
24
25
26
27 --方法2
28 declare @Str nvarchar(max)
29 set @str='select [LogDate]'
30 select @str=@str+',['+PathLine+']' from #CarLog group by PathLine
31 --exec @str
32 print @str
33 set @str=@str+' FROM (
34 SELECT LogDate,Amount,PathLine
35 FROM #CarLog ) AS c
36 PIVOT ( sum(Amount) FOR PathLine IN
37 ('
38 select @str=@str+'['+PathLine+'],' from #CarLog group by PathLine
39
40 set @str=left(@str,Len(@str)-1)
41 set @str=@str+ ')) AS thePivot
42 ORDER BY LogDate'
43 print @str
44
45 declare @Table table(Logdate datetime,1号线 int, 3号线 int,4号线 int,5号线 int,6号线 int)
46 INSERT INTO @Table exec(@str)
47 SELECT * FROM @Table
48 --drop table #T
49
50
51
52
53 select [LogDate],[1号线],[3号线],[5号线],[6号线] FROM (
54 SELECT LogDate,Amount,PathLine
55 FROM #CarLog ) AS cl
56 PIVOT ( sum(Amount) FOR PathLine IN
57 ([1号线],[3号线],[5号线],[6号线])) AS thePivot
58 ORDER BY LogDate
59 ----------------------------------分割线-----------------------------------------------------
60 CREATE TABLE [#StudentScores]
61 (
62 [UserName] NVARCHAR(20), --学生姓名
63 [Subject] NVARCHAR(30), --科目
64 [Score] FLOAT, --成绩
65 )
66
67 INSERT INTO [#StudentScores] SELECT 'Nick', '语文', 81
68 INSERT INTO [#StudentScores] SELECT 'Nick', '数学', 91
69 INSERT INTO [#StudentScores] SELECT 'Nick', '英语', 72
70 INSERT INTO [#StudentScores] SELECT 'Nick', '生物', 83
71 INSERT INTO [#StudentScores] SELECT 'Kent', '语文', 84
72 INSERT INTO [#StudentScores] SELECT 'Kent', '数学', 99
73 INSERT INTO [#StudentScores] SELECT 'Kent', '英语', 77
74 INSERT INTO [#StudentScores] SELECT 'Kent', '生物', 79
75 --drop table #StudentScores
76 ---------------------------
77 select * from #StudentScores
78
79 SELECT
80 UserName,
81 MAX(CASE Subject WHEN '语文' THEN Score ELSE 0 END) AS '语文',
82 MAX(CASE Subject WHEN '数学' THEN Score ELSE 0 END) AS '数学',
83 MAX(CASE Subject WHEN '英语' THEN Score ELSE 0 END) AS '英语',
84 MAX(CASE Subject WHEN '生物' THEN Score ELSE 0 END) AS '生物'
85 FROM dbo.[#StudentScores]
86 GROUP BY UserName
87
88 -----------------------------分割线----------------------------------------------------
89 CREATE TABLE [#Inpours]
90 (
91 [ID] [int] IDENTITY(1,1),
92 [UserName] NVARCHAR(20), --游戏玩家
93 [CreateTime] DATETIME, --充值时间
94 [PayType] NVARCHAR(20), --充值类型
95 [Money] DECIMAL, --充值金额
96 [IsSuccess] BIT, --是否成功 1表示成功, 0表示失败
97 CONSTRAINT [PK_Inpours_ID] PRIMARY KEY(ID)
98 )
99 INSERT INTO [#Inpours] SELECT '张三', '2010-05-01', '支付宝', 50, 1
100 INSERT INTO [#Inpours] SELECT '张三', '2010-06-14', '支付宝', 50, 1
101 INSERT INTO [#Inpours] SELECT '张三', '2010-06-14', '手机短信', 100, 1
102 INSERT INTO [#Inpours] SELECT '李四', '2010-06-14', '手机短信', 100, 1
103 INSERT INTO [#Inpours] SELECT '李四', '2010-07-14', '支付宝', 100, 1
104 INSERT INTO [#Inpours] SELECT '王五', '2010-07-14', '工商银行卡', 100, 1
105 INSERT INTO [#Inpours] SELECT '赵六', '2010-07-14', '建设银行卡', 100, 1
106
107 select * from #Inpours
108
109 SELECT CONVERT(VARCHAR(10), CreateTime, 120) AS CreateTime,
110 CASE PayType WHEN '支付宝' THEN SUM(Money) ELSE 0 END AS '支付宝',
111 CASE PayType WHEN '手机短信' THEN SUM(Money) ELSE 0 END AS '手机短信',
112 CASE PayType WHEN '工商银行卡' THEN SUM(Money) ELSE 0 END AS '工商银行卡',
113 CASE PayType WHEN '建设银行卡' THEN SUM(Money) ELSE 0 END AS '建设银行卡'
114 FROM #Inpours
115 GROUP BY CreateTime, PayType
116
117
118 ------
119 SELECT
120 CreateTime,
121 ISNULL(SUM([支付宝]), 0) AS [支付宝],
122 ISNULL(SUM([手机短信]), 0) AS [手机短信],
123 ISNULL(SUM([工商银行卡]), 0) AS [工商银行卡],
124 ISNULL(SUM([建设银行卡]), 0) AS [建设银行卡]
125 FROM
126 (
127 SELECT CONVERT(VARCHAR(10), CreateTime, 120) AS CreateTime,
128 CASE PayType WHEN '支付宝' THEN SUM(Money) ELSE 0 END AS '支付宝',
129 CASE PayType WHEN '手机短信' THEN SUM(Money) ELSE 0 END AS '手机短信',
130 CASE PayType WHEN '工商银行卡' THEN SUM(Money) ELSE 0 END AS '工商银行卡',
131 CASE PayType WHEN '建设银行卡' THEN SUM(Money) ELSE 0 END AS '建设银行卡'
132 FROM #Inpours
133 GROUP BY CreateTime, PayType
134 ) T
135 GROUP BY CreateTime
136 ------
137 DECLARE @cmdText VARCHAR(8000);
138 DECLARE @tmpSql VARCHAR(8000);
139
140 SET @cmdText = 'SELECT CONVERT(VARCHAR(10), CreateTime, 120) AS CreateTime,' + CHAR(10);
141 print @cmdText
142 SELECT @cmdText = @cmdText + ' CASE PayType WHEN ''' + PayType + ''' THEN SUM(Money) ELSE 0 END AS ''' + PayType
143 + ''',' + CHAR(10) FROM (SELECT DISTINCT PayType FROM #Inpours ) T
144 print @cmdText
145 SET @cmdText = LEFT(@cmdText, LEN(@cmdText) -2) --注意这里,如果没有加CHAR(10) 则用LEFT(@cmdText, LEN(@cmdText) -1)
146
147 SET @cmdText = @cmdText + ' FROM #Inpours GROUP BY CreateTime, PayType ';
148 print @cmdText
149 SET @tmpSql ='SELECT CreateTime,' + CHAR(10);
150 SELECT @tmpSql = @tmpSql + ' ISNULL(SUM(' + PayType + '), 0) AS ''' + PayType + ''',' + CHAR(10)
151 FROM (SELECT DISTINCT PayType FROM #Inpours ) T
152 print @tmpSql
153 SET @tmpSql = LEFT(@tmpSql, LEN(@tmpSql) -2) + ' FROM (' + CHAR(10);
154 print @tmpSql
155 SET @cmdText = @tmpSql + @cmdText + ') T GROUP BY CreateTime ';
156 PRINT @cmdText
157 EXECUTE (@cmdText);
158 -------
159 SELECT
160 CreateTime, [支付宝] , [手机短信],[工商银行卡] , [建设银行卡]
161 FROM
162 (
163 SELECT CONVERT(VARCHAR(10), CreateTime, 120) AS CreateTime,PayType, Money
164 FROM #Inpours
165 ) P
166 PIVOT (
167 SUM(Money)
168 FOR PayType IN
169 ([支付宝], [手机短信], [工商银行卡], [建设银行卡])
170 ) AS T
171 ORDER BY CreateTime
172
173 ----
174 /*
175 消息 325,级别 15,状态 1,第 9 行
176
177 'PIVOT' 附近有语法错误。您可能需要将当前数据库的兼容级别设置为更高的值,以启用此功能。有关存储过程 sp_dbcmptlevel 的信息,请参见帮助。
178 这个是因为:对升级到 SQL Server 2005 或更高版本的数据库使用 PIVOT 和 UNPIVOT 时,必须将数据库的兼容级别设置为 90 或更高。
179 有关如何设置数据库兼容级别的信息,请参阅 sp_dbcmptlevel (Transact-SQL)。
180 例如,只需在执行上面脚本前加上 EXEC sp_dbcmptlevel Test, 90; 就OK了, Test 是所在数据库的名称。
181 **/
182
183
184 ------------------------------------
185 CREATE TABLE #ProgrectDetail
186 (
187 ProgrectName NVARCHAR(20), --工程名称
188 OverseaSupply INT, --海外供应商供给数量
189 NativeSupply INT, --国内供应商供给数量
190 SouthSupply INT, --南方供应商供给数量
191 NorthSupply INT --北方供应商供给数量
192 )
193 --drop table #ProgrectDetail
194
195 INSERT INTO #ProgrectDetail
196 SELECT 'A', 100, 200, 50, 50
197 UNION ALL
198 SELECT 'B', 200, 300, 150, 150
199 UNION ALL
200 SELECT 'C', 159, 400, 20, 320
201 UNION ALL
202 SELECT 'D', 250, 30, 15, 15
203
204 select * from #ProgrectDetail
205 ------
206 SELECT ProgrectName, 'OverseaSupply' AS Supplier,
207 MAX(OverseaSupply) AS 'SupplyNum'
208 FROM #ProgrectDetail
209 GROUP BY ProgrectName
210 UNION ALL
211 SELECT ProgrectName, 'NativeSupply' AS Supplier,
212 MAX(NativeSupply) AS 'SupplyNum'
213 FROM #ProgrectDetail
214 GROUP BY ProgrectName
215 UNION ALL
216 SELECT ProgrectName, 'SouthSupply' AS Supplier,
217 MAX(SouthSupply) AS 'SupplyNum'
218 FROM #ProgrectDetail
219 GROUP BY ProgrectName
220 UNION ALL
221 SELECT ProgrectName, 'NorthSupply' AS Supplier,
222 MAX(NorthSupply) AS 'SupplyNum'
223 FROM #ProgrectDetail
224 GROUP BY ProgrectName
225 --------
226 SELECT ProgrectName,Supplier,SupplyNum
227 FROM
228 (
229 SELECT ProgrectName, OverseaSupply, NativeSupply,
230 SouthSupply, NorthSupply
231 FROM #ProgrectDetail
232 )T
233 UNPIVOT
234 (
235 SupplyNum FOR Supplier IN
236 (OverseaSupply, NativeSupply, SouthSupply, NorthSupply )
237 ) P
1 ----------------------行转列问题-----------------
2 CREATE TABLE #test(
3 EmployeeID INT,
4 CardTime DATETIME
5 );
6 go
7
8 INSERT INTO #test
9 SELECT 1, '2011-08-01 08:01:27' UNION ALL
10 SELECT 1, '2011-08-01 11:33:27' UNION ALL
11 SELECT 1, '2011-08-01 13:32:27' UNION ALL
12 SELECT 1, '2011-08-01 17:30:27' UNION ALL
13 SELECT 2, '2011-08-01 08:22:27' UNION ALL
14 SELECT 2, '2011-08-01 11:21:27' UNION ALL
15 SELECT 2, '2011-08-01 17:32:27'
16 go
17
18
19 --------------------------------
20 with myCTE AS (
21 SELECT
22 c.EmployeeID,
23 c.CardTime,
24 CASE
25 WHEN (convert(varchar(10), c.CardTime ,8) between '07:00:00' and '10:00:00')
26 THEN '上午上班时间'
27 WHEN ( convert(varchar(10), c.CardTime ,8) between '11:00:00' and '13:00:00')
28 THEN '上午下班时间'
29 WHEN ( convert(varchar(10), c.CardTime ,8) between '13:00:00' and '15:00:00')
30 THEN '下午上班时间 '
31 ELSE
32 '下午下班时间'
33 END as TimePart
34 FROM
35 #test c
36 )
37 SELECT
38 *
39 FROM
40 myCTE
41 PIVOT(
42 MIN(CardTime)
43 FOR TimePart IN ([上午上班时间], [上午下班时间], [下午上班时间], [下午下班时间] )
44 ) tmp
45
46 -----------------------------
47 with myCTE AS (
48 SELECT
49 c.EmployeeID,
50 CONVERT(varchar(10), c.CardTime, 120) AS CardDate,
51 c.CardTime,
52 CASE
53 WHEN (convert(varchar(10), c.CardTime ,8) between '07:00:00' and '10:00:00')
54 THEN '上午上班时间'
55 WHEN ( convert(varchar(10), c.CardTime ,8) between '11:00:00' and '13:00:00')
56 THEN '上午下班时间'
57 WHEN ( convert(varchar(10), c.CardTime ,8) between '13:00:00' and '15:00:00')
58 THEN '下午上班时间 '
59 ELSE
60 '下午下班时间'
61 END as TimePart
62 FROM
63 #test c
64 ),
65 baseCTE AS (
66 SELECT
67 EmployeeID,
68 CardDate,
69 MAX( CASE WHEN TimePart='上午上班时间' THEN CardTime ELSE NULL END ) AS [上午上班时间],
70 MIN( CASE WHEN TimePart='上午下班时间' THEN CardTime ELSE NULL END ) AS [上午下班时间],
71 MAX( CASE WHEN TimePart='下午上班时间' THEN CardTime ELSE NULL END ) AS [下午上班时间],
72 MIN( CASE WHEN TimePart='下午下班时间' THEN CardTime ELSE NULL END ) AS [下午下班时间]
73 FROM
74 myCTE
75 GROUP BY
76 EmployeeID,
77 CardDate
78 )
79 SELECT
80 EmployeeID,
81 CardDate,
82 [上午上班时间],
83 [上午下班时间],
84 [下午上班时间],
85 [下午下班时间],
86 CASE
87 WHEN (convert(varchar(10), [上午上班时间] ,8) between '08:35:00' and '10:00:00')
88 THEN 1
89 ELSE 0
90 END AS [上午迟到],
91 CASE
92 WHEN (convert(varchar(10), [上午下班时间] ,8) between '10:00:00' and '12:00:00')
93 THEN 1
94 ELSE 0
95 END AS
96 [上午早退],
97 CASE
98 WHEN (convert(varchar(10), [下午上班时间] ,8) between '14:05:00' and '15:00:00')
99 THEN 1
100 ELSE 0
101 END AS
102 [下午迟到],
103 CASE
104 WHEN (convert(varchar(10), [下午下班时间] ,8) between '17:00:00' and '17:30:00')
105 THEN 1
106 ELSE 0
107 END AS [下午早退]
108 FROM
109 baseCTE;
将查询出来的结果集转换为XML类型
1 /**
2 Select 的查询结果会作为行集返回,但是你同样可以在sql中指定for xml子句使得查询作为xml来检索。
3 在for xml子句中,可以指定以下模式之一:RAW 、AUTO、EXPLICIT和PATH。
4 RAW模式返回行为元素,每一列的值作为元素的属性;
5 AUTO模式返回表名为节点的元素,每一列的属性作为属性输出;
6 EXPLICIT模式通过SELECT语法定义输出XML结构;
7 PATH模式中列名或列别名作为XPATH表达式来处理。
8 **/
9 --xml raw
10 SELECT TOP 5 CCode,CName FROM dbo.city FOR XML RAW
11 --xml auto
12 SELECT TOP 5 ProductName,UnitPrice FROM dbo.Products FOR XML AUTO
13 --xml explict
14 SELECT TOP 5 1 AS Tag,0 AS Parent, PCode AS [Province!1!ID],PName AS [Province!1!Name],PCode AS [Province!1!Customer],NULL AS [City!2!ID],NULL AS [City!2!CName],NULL AS [City!2!CityID]
15 FROM dbo.Province WHERE dbo.Province.PCOde=''
16 UNION ALL
17 SELECT TOP 5 2 AS Tag,1 AS Parent, NULL,NULL ,NULL,ID,CName,0 FROM dbo.city WHERE PCOde=''
18 FOR XML EXPLICIT
19 --PATH
20 SELECT TOP 5 CName AS CityName, CCode AS CityID FROM dbo.City FOR XML PATH('City')
21 /**
22 RAW模式和AUTO模式相对比较简单,灵活性当然也是比较差的。
23 EXPLICIT模式会将查询执行生成的行集转换为XML文档,也就是说结构可以自定义,当然这必须符合一定的格式。
24 就拿上面的语句来说:Tag指定生成节点的嵌套级别,列名必须为"Tag"例如上面的级别为1。
25 Parent指定当前Tag的父级层次,列名必须为"Parent",NULL表示顶级。
26 其他列名,例如[Order!1!ID]分别代表元素名称、Tag标记(也就是层级)、属性名称。
27 例如上面的这一列就代表会在第一级节点中生成一个节点名称为Order的节点并且有一个属性ID。
28 此外还需要指出的是这个列名还有一个可选部分,完整的形式是[ElementName!TagNumber!AttributeName!Directive]
29 ,最后一部分Directive是可选的,如果不指定的话默认作为ElementName中的属性名称;
30 当然如果制定了xml、cdata或者element那么它将作为ElementName的一个子元素而不是属性。
31 并且指定了此选项之后AttributeName可以为空。
32 上面的例子中如果去掉For XML EXPLICIT之后查询到的数据时如下形式:
33
34 按照上面的规则不难看出,FOR XML EXPLICIT会按照顺序生成xml:
35 第一次执行(第一行数据)时tag为1,parent为0,
36 则此时会按照列名创建一个Order节点,并依次创建三个属性:ID、Date和Customer,
37 其值为:10248、1996-07-04 00:00:00.000、VINET。此时不会生成ProductID属性,
38 因为它的Tag为2,需要在第二级节点中创建,其他另个属性也是如此。
39 第二次执行(第二行数据)时Tag为2,Parent为1,
40 也就是要在Tag为1的节点中创建一个2级节点。
41 然后根据查找列名中Tag为2的列,依次创建ProductID、UnitPrice、Quantity属性,并赋值。
42 第三次、第四次同第二次执行类似,不同的只是数据而已。
43 PATH模式应该说是使用率相当高的,原因比较简单,它的使用既简单又灵活。
44 在PATH模式中,节点名称可以使列名也可以通过别名指定又或者根本不指定,不指定的情况下就只显示节点内数据;
45 根节点可以指定也可以不指定,不指定情况下默认为"row",并且根节点指定为""的情况下可以完全取消根节点的显示。
46 有了这一属性就可以使用PATH模式完成很多有用的操作。
47 没有指定根节点时:
48
49 */
50 --没有指定根节点时
51 SELECT TOP 5 CName FROM dbo.City FOR XML PATH
52 --去掉根节点名称
53 SELECT TOP 5 CName FROM dbo.City FOR XML PATH('')
54 --去掉根节点和子节点名称
55 SELECT TOP 5 CName+',' FROM dbo.City FOR XML PATH('')
56 --可以发现去掉节点名称之后for xml path起到了字符串连接的作用,这样一来就可以利用这一特性完成字符串拼接
57 SELECT LEFT(CName,(LEN(CName)-1)) FROM(
58 SELECT
59 (SELECT TOP 5 CName+',' FROM dbo.City FOR XML PATH('')) AS CName
60 ) AS T
61
62
63 select * from City
当遇到夸库查询时,可以采用这种方法:
库名.dbo.表名,当然更加建议您使用 不同的数据库连接语句来操作
前段时间,才更加清楚地认识到了COUNT(字段)与COUNT(*)之间的区别,亡羊补牢,为时不晚
1 最后一个介绍的函数就是统计记录数量的COUNT,这个函数有一点特别,因为它的即可以
2 像其他聚合函数一样使用字段名做参数,也可以使用星号“*”做为参数。我们执行下面的SQL:
3 SELECT COUNT(*),COUNT(FNumber) FROM T_Employee
4 执行完毕我们就能在输出结果中看到下面的执行结果:
5 8 8
6 可以看到COUNT(*)、COUNT(FNumber)两种方式都能统计出记录的条数,据此为数不少
7 的开发人员都认为COUNT(*)、COUNT(字段名)这两种使用方式是等价的。下面通过例子来说
8 明,为了看到两种使用方式的区别需要首先向表T_Employee 中插入一条新的数据,执行下面
9 的SQL:
10 INSERT INTO T_Employee(FNumber,FAge,FSalary) VALUES('IT002',27,2800)
11 需要注意的就是这句INSERT语句没有为FName 字段赋值,也就是说新插入的这条数据的
12 FName 字段值为空,可以执行SELECT * FROM T_Employee 来查看表T_Employee 中的
13 内容:
14 FNumber FName FAge FSalary
15 DEV001 Tom 25 8300.00
16 DEV002 Jerry 28 2300.80
17 HR001 Jane 23 2200.88
18 HR002 Tina 25 5200.36
19 IT001 Smith 28 3900.00
20 IT002 <NULL> 27 2800.00
21 SALES001 John 23 5000.00
22 SALES002 Kerry 28 6200.00
23 SALES003 Stone 22 1200.00
24 可以看到FNumber 为IT002 的行的FName字段是空值。接着执行下面的SQL:
25 SELECT COUNT(*),COUNT(FNumber),COUNT(FName) FROM T_Employee
26 执行完毕我们就能在输出结果中看到下面的执行结果:
27 9 9 8
28 可以看到COUNT(*)、COUNT(FNumber)两个表达式的计算结果都是9,而COUNT(FName)
29 的计算结果是8。也就反应出了两种使用方式的区别:COUNT(*)统计的是结果集的总条数,而
30 COUNT(FName)统计的则是除了结果集中FName 不为空值(也就是不等于NULL)的记录的总
31 条数。由于FNumber 为IT002 的行的FName 字段是空值,所以COUNT(FName)的计算结果
32 是8。因此在使用聚合函数COUNT 的时候一定要区分两种使用方式的区别,以防止出现数据错
33 误。
34 [[提示:如果查询出来的条件没有NULL值 ,那么俩种查询条件无任何区别。]]
不知道,您有没有在你的项目中这样来使用GOTO语句
1 /**
2 GOTO语句可以实现无条件跳转
3 语法格式 GOTO lable 其中lable为要跳转到的语句标号
4 遇到GOTO语句时直接跳转到lable标签处继续执行,而goto之后的语句不再执行
5 **/
6
7 declare @result int=0
8 declare @sn int =0
9 loop_1:--定义标号
10 set @result=@result+@sn
11 set @sn=@sn+1
12 if(@sn<=100)
13 goto loop_1--如果小于100就跳转到loop_1标号处
14 print @result
不知道,您有没有在SQLServer中尝试连接过Access?
1 ---------------在SQLServer中连接Access数据库----------------
2
3 --启用Ad Hoc Distributed Queries:
4 exec sp_configure 'show advanced options',1
5 reconfigure
6 exec sp_configure 'Ad Hoc Distributed Queries',1
7 reconfigure
8 --使用完成后,关闭Ad Hoc Distributed Queries:
9 exec sp_configure 'Ad Hoc Distributed Queries',0
10 reconfigure
11 exec sp_configure 'show advanced options',0
12 reconfigure
13
14
15 SELECT *
16 FROM OpenDataSource( 'Microsoft.Jet.OLEDB.4.0','Data Source="D:\worksystem.mdb";User ID=Admin;Password=;Extended properties=Excel 5.0')...TimeRecords
17
18 SELECT *
19 FROM OpenDataSource( 'Microsoft.Jet.OLEDB.4.0','Data Source="D:\worksystem.mdb";User ID=Admin;Password=;')...TimeRecords
20
21 SELECT *
22 FROM OpenDataSource( 'Microsoft.Jet.OLEDB.4.0','Data Source="D:\worksystem.mdb";Jet OLEDB:Database Password=;')...TimeRecords
针对分页,有很多类型,不过下面这几种,都是自己在网上集锦下来的,在这里感谢博客园感谢自己的老总MVP,本着分享的目的,再在这里啰嗦一下^
1 USE [test]
2 GO
3 /****** Object: StoredProcedure [dbo].[PageIndex] Script Date: 12/07/2011 10:26:36 ******/
4 SET ANSI_NULLS ON
5 GO
6 SET QUOTED_IDENTIFIER ON
7 GO
8 ALTER PROCEDURE [dbo].[PageIndex]
9 (
10 @Tbname varchar(100),--表名字
11 @Strfield varchar(100),--查询字段
12 @idfield varchar(50),--主键ID
13 @Toppage int=10,--每页行数
14 @PageNow int=0,--查询页数
15 @strWhere varchar(100) ='1=1',--查询条件
16 @Pagecount int=0 output,--总页数
17 @order varchar(200)=''--排序条件
18 )
19 AS
20 DECLARE @sql nvarchar(1000),
21 @sqloder varchar(200)
22 BEGIN
23 if(@Pagecount=0)--总页数
24 begin
25 declare @page int
26 set @sql= 'select @Page=COUNT('+@idfield+') from '+@Tbname+ ' where '+@strWhere
27 print @sql
28 exec sp_executesql @sql,N'@Page int output',@Page output--查询总行数
29 SELECT @pageCount=CEILING((@page+0.0)/@Toppage) --计算页数
30 print @pageCount
31 end
32 if(@order!='')--排序条件
33 begin
34 set @sqloder='ORDER BY '+@order
35 end
36 else
37 begin
38 set @sqloder=''
39 end
40 if(@strWhere!='')--查询条件
41 begin
42 set @strWhere='where '+@strWhere
43 end
44 begin--执行SQL语句
45 --/*
46 set @sql='SELECT TOP '
47 +cast(@Toppage as varchar(200))+
48 ' '+@Strfield+' FROM (SELECT '+@Strfield+',ROW_NUMBER() OVER (ORDER BY '
49 +@order+') AS RowNumber
50 FROM '+@Tbname+') A WHERE RowNumber > '
51 +cast(@Toppage as varchar(200))+' * ('
52 +cast(@PageNow as varchar(200))+'-1) '+@sqloder
53 --*/
54 --print @sql
55 /*set @sql ='SELECT TOP '+cast(@Toppage as varchar(200))+' '+@Strfield+ '
56 FROM '+@Tbname+'
57 WHERE '+@idfield+' >
58 (
59 SELECT ISNULL(MAX('+@idfield+'),0)
60 FROM
61 (
62 SELECT TOP ('+cast(@Toppage as varchar(200))+'*('+cast(@PageNow as varchar(200))+'-1))
63 '+@idfield+' FROM '+@Tbname+' '+@sqloder+'
64 ) A
65 ) '+@sqloder*/
66 print (@sql)
67 exec (@sql)
68
69 end
70 END
其实分页也可以这样来写
1 --假设数据库中有张表,表名是UserName,字段分别是ID(int),Name(nvarchar),Age(int)。
2 --如果不带查询条件存储过程是:
3 CREATE PROCEDURE [dbo].[UserName]
4 @pageIndex int,
5 @pageSize int
6 AS
7 declare @min int;
8 declare @max int;
9 set @min=@pageSize*(@pageIndex-1)+1;
10 set @max=@pageSize*@pageIndex;
11 with myTable as(select ID,Name,Age,Row_Number() over (order by ID) as rownum from [UserName] )
12 select ID,Name,Age from myTable where rownum between @min and @max
13 RETURN
14 --这个分页存储过程很不实用,并且表是固定的。
15 --下面十二个万能分页存储过程,
16 CREATE PROCEDURE [dbo].[UP_GetRecordByPage]
17 @tblName varchar(255), -- 表名
18 @fldName varchar(255), -- 主键字段名
19 @PageSize int , -- 页尺寸
20 @PageIndex int , -- 页码
21 @IsReCount bit, -- 返回记录总数, 非 0 值则返回
22 @OrderType bit, -- 设置排序类型, 非 0 值则降序
23 @strWhere varchar(1000) = '' -- 查询条件 (注意: 不要加 where)
24 AS
25 declare @strSQL varchar(6000) -- 主语句
26 declare @strTmp varchar(2000) -- 临时变量(查询条件过长时可能会出错,可修改100为1000)
27 declare @strOrder varchar(400) -- 排序类型
28 if @OrderType != 0
29 begin
30 set @strTmp = '<(select min'
31 set @strOrder = ' order by [' + @fldName +'] desc'
32 end
33 else
34 begin
35 set @strTmp = '>(select max'
36 set @strOrder = ' order by [' + @fldName +'] asc'
37 end
38 set @strSQL = 'select top ' + str(@PageSize) + ' * from ['
39 + @tblName + '] where [' + @fldName + ']' + @strTmp + '(['
40 + @fldName + ']) from (select top ' + str((@PageIndex-1)*@PageSize) + ' ['
41 + @fldName + '] from [' + @tblName + ']' + @strOrder + ') as tblTmp)'
42 + @strOrder
43 if @strWhere != ''
44 set @strSQL = 'select top ' + str(@PageSize) + ' * from ['
45 + @tblName + '] where [' + @fldName + ']' + @strTmp + '(['
46 + @fldName + ']) from (select top ' + str((@PageIndex-1)*@PageSize) + ' ['
47 + @fldName + '] from [' + @tblName + '] where ' + @strWhere + ' '
48 + @strOrder + ') as tblTmp) and ' + @strWhere + ' ' + @strOrder
49 if @PageIndex <> 0
50 begin
51 set @strTmp =''
52 if @strWhere != ''
53 set @strTmp = ' where ' + @strWhere
54 set @strSQL = 'select top ' + str(@PageSize) + ' * from ['
55 + @tblName + ']' + @strTmp + ' ' + @strOrder
56 exec (@strSQL)
57 end
58 if @IsReCount != 0
59 begin
60 set @strSQL = 'select count(*) as Total from [' + @tblName + ']'+' where ' + @strWhere
61 exec (@strSQL)
62 end
63 --使用方法:
64 EXEC dbo.UP_GetRecordByPage @tblName = ‘UserName’, -- varchar(255)
65 @fldName = 'ID', -- varchar(255)
66 @PageSize = 2, -- int
67 @PageIndex = 1, -- int
68 @IsReCount = 0, -- bit
69 @OrderType = 1, -- bit
70 @strWhere = 'Age=13' -- varchar(1000)
71 --如果哪里有不正确的地方,欢迎批评指正,共同进步。
当然还有更简单的分页
1 --查询第20-30条
2 select top 10 * from Sales where ID>
3 (select max(ID) from
4 (select top 20 ID from Sales order by ID ASC ) t0
5 )
6 order by ID ASC
不知道您对于在SQL语句中拼接字符串是否常用
1 --行转列
2 create table #CarLog(LogDate datetime,PathLine nvarchar(10),Amount int)
3 --drop table #CarLog
4 insert into #CarLog(LogDate,PathLine,Amount)VALUES('2011-12-24','1号线',1)
5 insert into #CarLog(LogDate,PathLine,Amount)VALUES('2011-12-25','1号线',91)
6 insert into #CarLog(LogDate,PathLine,Amount)VALUES('2011-12-26','1号线',66)
7 insert into #CarLog(LogDate,PathLine,Amount)VALUES('2011-12-24','3号线',44)
8 insert into #CarLog(LogDate,PathLine,Amount)VALUES('2011-12-24','3号线',33)
9 insert into #CarLog(LogDate,PathLine,Amount)VALUES('2011-12-24','5号线',12)
10 insert into #CarLog(LogDate,PathLine,Amount)VALUES('2011-12-24','6号线',22)
11
12 select * from #CarLog
13
14 declare @s nvarchar(4000)
15 set @s=''
16 select @s=@s+',' +PathLine from #CarLog
17 print @s
当然也可以使用SQL来生成随机密码(以前博客园有文章说过……)
http://www.cnblogs.com/insus
-----------------------随机产生密码的存储过程
create PROCEDURE [dbo].[usp_RandomPassword]
(
@Length INT = 8
)
AS
BEGIN
DECLARE @RandomPassword NVARCHAR(MAX) = N'',@L INT = 1
--下面的变量,你可以自定制需要的特殊字符
DECLARE @SpecialCharacter NVARCHAR(255) = '@#$%&*?'
WHILE @L <= @Length
BEGIN
--下面这句,Insus.NET把2改为3。
DECLARE @R INT = ROUND(RAND() * 3, 0)
SET @RandomPassword = @RandomPassword + CASE @R
WHEN 0 THEN CHAR(ROUND(RAND() * 9 + 48,0))
WHEN 1 THEN CHAR(ROUND(RAND() * 25 + 65,0))
WHEN 2 THEN CHAR(ROUND(RAND() * 25 + 97,0))
WHEN 3 THEN SUBSTRING(@SpecialCharacter, CONVERT(TINYINT,ROUND(RAND() * 6 + 1,0)),1) END --添加此句
SET @L = @L + 1
END
SELECT @RandomPassword
END --- dbo.[usp_RandomPassword]
alter PROCEDURE [dbo].[usp_RandomPassword]
(
@Length INT = 8
)
AS
BEGIN
DECLARE @RandomPassword NVARCHAR(MAX) = N'',@L INT = 1
WHILE @L <= @Length --循环密码长度
BEGIN
--随机产生每一位字符,ASCII码48至122
DECLARE @RndChar CHAR(1) = CHAR(ROUND(RAND() * (122-48+1) + 48,0))
--随机产生的字符不包括下面字符
IF ASCII(@RndChar) NOT IN(58,59,60,61,62,63,64,91,92,93,94,95,96) -- : , ; , < , = , > , ? ,@ , [ , \ , ] , ^ , _ , `
BEGIN
SET @RandomPassword = @RandomPassword + @RndChar
SET @L = @L + 1
END
END
SELECT @RandomPassword
END
-----------------------随机产生密码的存储过程
alter PROCEDURE [dbo].[usp_RandomPassword]
(
@Length INT = 8
)
AS
BEGIN
DECLARE @RandomPassword NVARCHAR(MAX) = N'',@L INT = 1
--随机密码将由下面字符串产生,数字0-9,大写字母A-Z,小写字母a-z
DECLARE @BaseString VARCHAR(255) = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
WHILE @L <= @Length --循环密码长度
BEGIN
--61是变量@BaseString的长度减一
SET @RandomPassword = @RandomPassword + SUBSTRING(@BaseString, CONVERT(INT,ROUND(RAND() * 61 + 1,0)),1)
SET @L = @L + 1
END
SELECT @RandomPassword
END -----------------------随机产生密码的存储过程
CREATE PROCEDURE [dbo].[usp_RandomPassword]
(
@Length INT = 8
)
AS
BEGIN
DECLARE @RandomPassword NVARCHAR(MAX) = N''
DECLARE @R TINYINT,@L INT = 1
WHILE @L <= @Length --循环密码长度
BEGIN
SET @R = ROUND(RAND() * 2, 0) --随机产生0,1,2整数
IF @R = 0 --当变量为0时,将随机产生一位数字
SET @RandomPassword = @RandomPassword + CHAR(ROUND(RAND() * 9 + 48,0))
ELSE IF @R = 1 --当变量为1时,将随机产生一位大写字母
SET @RandomPassword = @RandomPassword + CHAR(ROUND(RAND() * 25 + 65,0))
ELSE IF @R = 2 --当变量为2时,将随机产生一位小写字母
SET @RandomPassword = @RandomPassword + CHAR(ROUND(RAND() * 25 + 97,0))
SET @L = @L + 1
END
SELECT @RandomPassword
END
----------重构
CREATE PROCEDURE [dbo].[usp_RandomPassword]
(
@Length INT = 8
)
AS
BEGIN
DECLARE @RandomPassword NVARCHAR(MAX) = N'',@L INT = 1
WHILE @L <= @Length --循环密码长度
BEGIN
DECLARE @R INT = ROUND(RAND() * 2, 0)
SET @RandomPassword = @RandomPassword + CASE @R
WHEN 0 THEN CHAR(ROUND(RAND() * 9 + 48,0))
WHEN 1 THEN CHAR(ROUND(RAND() * 25 + 65,0))
WHEN 2 THEN CHAR(ROUND(RAND() * 25 + 97,0)) END
SET @L = @L + 1
END
SELECT @RandomPassword
END
-----------------------
--MS SQL有一个函数CHAR()是将int(0-255) ASCII代码转换为字符
--下面MS SQL语句,可以随机生成小写、大写字母,特殊字符和数字。
--大写字母:
select CHAR(ROUND(RAND() * 25 + 65,0)) --小写字母:
select CHAR(ROUND(RAND() * 25 + 97,0)) --特殊字符:
select CHAR(ROUND(RAND() * 13 + 33,0)) --数字:
select CHAR(ROUND(RAND() * 9 + 48,0)) ----------------------------------
--随机密码首字符不能为数字与特殊字符但必须包含且只有一个特殊字符
--修正了特殊字符集长度问题,使用特殊字符集长度减一(LEN(@SpecialCharacter) - 1) 这样当你增减特殊字符集时,再不需多次地方一同修改
ALTER PROCEDURE [dbo].[usp_RandomPassword]
(
@Length INT = 8
)
AS
BEGIN
DECLARE @RandomPassword NVARCHAR(MAX) = N''
DECLARE @SpecialCharacter NVARCHAR(255) = N'@#$%&*?' --特殊字符集
DECLARE @HasSpcCht BIT = 0 --判断产生的随机数是否有包含随机数
DECLARE @L INT = 1 DECLARE @R TINYINT,@R1 TINYINT,@R2 TINYINT
WHILE @L <= @Length --循环密码长度,每一位字符将随机产生
BEGIN
IF @L = 1 --随机数第一位只为字母,大写或小写
BEGIN
SET @R = ROUND(RAND() * 1, 0)
SET @RandomPassword = @RandomPassword + CASE @R
WHEN 0 THEN CHAR(ROUND(RAND() * 25 + 97,0))
WHEN 1 THEN CHAR(ROUND(RAND() * 25 + 65,0))
END
END
ELSE
BEGIN
IF @L = @Length AND @HasSpcCht = 0 --当最后一位时,如果没有产生过特殊字符,那为随机数产生一个。
BEGIN
SET @RandomPassword = @RandomPassword + SUBSTRING(@SpecialCharacter, CONVERT(TINYINT,ROUND(RAND() * (LEN(@SpecialCharacter) - 1) + 1,0)),1)
SET @HasSpcCht = 1
END
ELSE
BEGIN
SET @R1 = ROUND(RAND() * 3, 0)
IF @R1 = 0
SET @RandomPassword = @RandomPassword + CHAR(ROUND(RAND() * 25 + 97,0)) IF @R1 = 1
SET @RandomPassword = @RandomPassword + CHAR(ROUND(RAND() * 25 + 65,0)) IF @R1 = 2
SET @RandomPassword = @RandomPassword + CHAR(ROUND(RAND() * 9 + 48,0)) IF @R1 = 3 --随机产生特殊字符
BEGIN
IF @HasSpcCht = 0 --如果没有产生过,那为随机数产生一个。
BEGIN
SET @RandomPassword = @RandomPassword + SUBSTRING(@SpecialCharacter, CONVERT(TINYINT,ROUND(RAND() * (LEN(@SpecialCharacter) - 1) + 1,0)),1)
SET @HasSpcCht = 1
END
ELSE --如果已经产生过特殊字符,只循环产生字母,或数字
BEGIN
SET @R2 = ROUND(RAND() * 2, 0)
SET @RandomPassword = @RandomPassword + CASE @R2
WHEN 0 THEN CHAR(ROUND(RAND() * 25 + 97,0))
WHEN 1 THEN CHAR(ROUND(RAND() * 25 + 65,0))
WHEN 2 THEN CHAR(ROUND(RAND() * 9 + 48,0))
END
END
END
END
END SET @L = @L + 1 --随机产生一位,随机数位数加一位。
END
SELECT @RandomPassword
END
不知道您是否还记得数据库连接字符串如何来写?
1 1.连接sqlserver的连接字符串是:
2 “server=.;database=数据库名;uid=用户名;pwd=密码”
3 1.连接VS内置的数据库的连接字符串是:
4 DataSource=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\App.mdf;Integrated Security=True;User Instance=True"
5 下面我说明下这连接字符串的意思:
6 "Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Student.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True";
7 DataSource相当于server
8 DataSource=.\SQLEXPRESS:是本机下的数据库实例SQLEXPRESS
9 AttachDbFilename=|DataDirectory|\App.mdf附加项目App_Data下的App.mdf
10 Integrated Security=True;User Instance=True"一个是将整体安全性设置为true,一个是将用户实例设置为true
曾经在博客园火热一时的T-SQL文章,经过本人整理的
1 --查询所有数据库
2 use master
3 select * from sysdatabases where dbid>4;--系统自带的数据库分别是master->1,model->3,msdb->4,tempdb->2
4
5
6 --查询数据库中所有数据库(存储过程)
7 exec sp_helpdb;
8
9 --查询指定数据库中的表
10 use master
11
12 select * from sysobjects where xtype='u' ;
13 if object_id('#test1') is not null
14 drop table #test1
15 go
16
17 create table #test1
18 (
19 id int not null primary key,
20 name nvarchar default('haha')
21 )
22
23 drop table #test1
24
25 set nocount off
26
27 select name from sysobjects where xtype='u'--读数据库中表名
28
29 select name from syscolumns where id=(select max(id) from sysobjects where xtype='u' and name='表名')--读取某表的列名
30
31 --exec调用保存在变量中的批处理代码
32 declare @sql as varchar(100);
33 set @sql='print''this is a message......;'';';
34 exec(@sql)
35
36 ----------------------------------------
37 --DDL--数据定义语言
38 --DML--数据操作语言
39
40 --数据库定期备份
41 if day(current_timestamp)=9
42 begin
43 print '今天是一个月的第一天,数据库备份'
44 print '开始完全备份'
45 backup database dbtest to disk='E:\backup\backup_dbtest_full.bak' with init;
46 print '完全备份成功'
47 end
48 else
49 begin
50 print '今天是一个月的最后一天,数据库备份'
51 print '开始差异备份'
52 backup database dbtest to disk='E:\backup\backup_dbtest_diff.bak' with differential;
53 print '差异备份成功'
54 end
55
56 ------------------------------------------------------------
57 use tempdb;
58
59 if object_id('dbo.Orders','u') is not null drop table dbo.Orders;
60 create table dbo.Orders
61 (
62 orderid int not null
63 constraint pk_order primary key,
64 orderdate datetime not null
65 constraint def_orderdate default(current_timestamp)
66 )
67
68
69 ----------------子查询--------------------------------------------
70 --子查询分为1-独立子查询2-相关子查询
71 --返回结果可以是一个单独的值(标量)或者多个值或者整个表变量
72 declare @maxid as int = (select max(orderid) from Sales.Orders);
73 select orderid,orderdate,empid,custid
74 from Sales.Orders
75 where orderid=@maxid;
76
77 --sql2005
78 select orderid,orderdate,empid,custid
79 from Sales.Orders
80 where orderid=(select max(orderid) from Sales.Orders);
81 --对于有效的标量子查询,它的返回值不能超过一个,如果标量子查询返回了多个值,在运行时可能会失败。
82 --比如
83 select orderid
84 from Sales.Orders
85 where empid=(select E.empid from HR.Employees as E where E.lastname like N'B%')
86 select E.lastname from HR.Employees as E
87 --因为恰巧该表中只有一个人的名字是以B开头的所以,sql会认为右边子查询是标量值
88 --假如右边表达式没有返回任何值,那么两者比较得出的结果是NULL,而与NULL比较的结果都为UNKNOW,所以不会返回任何值
89 --当然上面的查询还可以用联结查询
90 select O.orderid
91 from HR.Employees as E
92 join Sales.Orders as O
93 on E.empid=O.empid
94 where E.lastname like N'D%'
95
96 --独立多值子查询IN------
97 --<标量表达式> IN <多值子查询>
98
99
100 --用某表的偶数行数据填充tempdb
101 use tempdb
102 select *
103 into dbo.tempdb
104 from TSQLFundamentals2008.Sales.Orders
105 where orderid%2=0;
106
107 select * from tempdb;
108
109 --返回tempdb中介于min(orderid)与max(orderid)并且不在表中的orderid
110 select n
111 from tempdb
112 where n between (select min(O.orderid) from tempdb as O) and (select max(E.orderid) from tempdb as E)
113 and n not in(select orderid from tempdb);
114
115 -------------------------游标使用-------------------------------------------
116 --游标通常步骤
117 --1.在某个查询的基础上声明游标
118 --2.打开游标
119 --3.从第一个游标记录中把列值提取到指定的变量
120 --4.当还没有超出游标最后一行时,(@@fetch_status函数返回值为0),循环遍历游标记录,在每一次遍历中,从当前游标记录把列
121 --值提取到指定的变量,再为当前执行相应的处理
122 --5.关闭游标
123 --6.释放游标
124 use TSQLFundamentals2008
125 declare @result table
126 (
127 custid int,
128 ordermonth datetime,
129 qty int,
130 runqty int,
131 primary key(custid,ordermonth)
132 );
133
134 declare
135 @custid as int,
136 @prvcustid as int,
137 @ordermonth as datetime,
138 @qty as int,
139 @runqty as int;
140 declare c cursor fast_forward for
141 select custid,ordermonth,qty
142 from Sales.CustOrders
143 order by custid,ordermonth;
144
145 open c
146 fetch next from c into @custid,@ordermonth,@qty;
147 select @prvcustid=@custid,@runqty=0;
148 while @@fetch_status=0
149 begin
150 if @custid<>@prvcustid
151 set @runqty=@runqty+@qty;
152 insert into @result values(@custid,@ordermonth,@qty,@runqty);
153 fetch next from c into @custid,@ordermonth,@qty;
154 end
155 close c;
156 deallocate c;
157 select custid,convert(varchar(7),ordermonth,121) as ordermonth,qty,runqty
158 from @result
159 order by custid,ordermonth;
160
161
162 -------------------------------------------
163 --1)接受数据导入的表已经存在。
164 insert into t1 select * from OPENROWSET('MICROSOFT.JET.OLEDB.4.0' ,
165 'Excel 5.0;HDR=YES;DATABASE=c:\\test.xls',sheet1$);
166 --2)导入数据并生成表。
167 select * into t1 from OPENROWSET('MICROSOFT.JET.OLEDB.4.0',
168 'Excel 5.0;HDR=YES;DATABASE=c:\\test.xls',sheet1$);
169 --
170 --3) 导入Excel中指定的列到数据库表中指定的列。
171 INSERT INTO t1(a1,a2,a3) SELECT a1,a2,a3 FROM OPENROWSET 'MICROSOFT.JET.OLEDB.4.0' ,'Excel5.0; HDR=YES; DATABASE=c:\\test.xls',sheet1$);
172 --
173 --需要注意的地方。
174 --1)外围应用配置器的设置。
175 -- 从“功能外围应用配置器”中选择“启动 OPENROWSET 和 OPENDATASOURCE 支持”选项。
176 --2)关闭Excel表。
177 -- 如果在导入时要导入的Excel表格处于打开状态,会提示:
178 -- “无法初始化链接服务器 "(null)" 的 OLE DB 访问接口 "microsoft.jet.oledb.4.0" 的数据源对象。”
179 --3)导入数据时,Excel的首行会作为表头,若导入到已存在的数据库表,则忽略首行。
180
181
182 --------------------------------------直接从数据库将表导出到EXCEL-------------------------------------------------------------
183 EXEC master..xp_cmdshell 'bcp master.dbo.t2 out d:\Temp.xls -c -q -S"127.0.0.1" -U"sa" -P"123456"'
184
185 --参数:S 是SQL服务器名;U是用户;P是密码
186
187
188
189
190 --查询优化------------------------------------------
191 set nocount on;
192 use master;
193 if db_id('performance') is null
194 create database performance;
195 go
196 use performance;
197 go
198
199 --创建填充的数字辅助表
200 set nocount on;
201 if object_id('dbo.nums','u') is not null
202 drop table nums;
203 create table dbo.nums(n int not null primary key);
204
205 declare @max as int,@rc as int;
206 set @max=1000;
207 set @rc=1;
208
209 insert into dbo.nums(n) values(1);
210 while @rc*2<=@max
211 begin
212
213 insert into dbo.nums(n) select n+@rc from dbo.nums;
214 set @rc=@rc*2;
215 end
216
217 insert into dbo.nums(n) select n+@rc from dbo.nums where n+@rc<=@max;
218 go
219
220 --如果数据表存在,则先删除
221
222
223 ------------------------------------------------------------
224 use insideTSQL2008;
225
226 set nocount off;
227
228 select orderid,custid
229 from sales.orders
230 where orderid=(select max(orderid) from sales.orders );--取出orderid最大的订单信息(标量子查询)
231
232 -------相关子查询,返回每个客户最大的订单信息
233 select orderid,custid
234 from sales.orders as T1
235 where orderid=(select max(orderid) from sales.orders as T2 where T1.custid=T2.custid)
236 order by custid;
237
238 ---在期待多个值的地方可以使用多值子查询,返回下过订单的客户
239 select custid,companyname
240 from sales.customers
241 where custid not in (select custid from sales.orders);
242
243 --在期待表的地方还可以使用 表值子查询 或 表表达式
244 --查询每个订单年份返回最大的订单ID
245 select * from sales.orders;
246 select * from sales.customers;
247 select order_year,max(orderid) as max_orderid
248 from (select orderid,year(orderdate) as order_year from sales.orders) as T1
249 group by order_year;
250
251 --子查询可以按两种方式进行分类,按期望值的数量可以分为标量子查询,多值子查询
252 --按子查询对外部的依赖,分为独立子查询,相关子查询,标量子查询和多值子查询既可以是独立子查询,也可以是相关子查询
253 --查询由每个美国雇员至少为其处理过的一个订单的所有客户
254 --假设知道美国雇员的empid是1,2,3,4,8
255 --(1)
256 select custid
257 from sales.orders
258 where empid in(1,2,3,4,8)
259 group by custid
260 having count( distinct empid)=5;
261 --(2)
262 select custid
263 from sales.orders
264 where empid in (select empid from hr.employees where country='usa')
265 group by custid
266 having count(distinct empid)=5
267
268 --返回每个月最后实际订单日期发生的订单
269 select orderid,custid,empid,orderdate
270
271 from sales.orders
272 where orderdate in(
273 select max(orderdate)
274 from sales.orders
275 group by year(orderdate),month(orderdate));
276
277 --相关子查询,是引用了在外部查询中出现的列的子查询,从逻辑上讲,子查询会为外部查询的每一行进行一次计算。
278 --决胜属性(tiebreaker),是一个属性或属性列表,可以惟一的对元素进行排名
279
280 --先创建2张表
281 use master;
282
283 if db_id('DbTest') is not null drop database DbTest;
284
285 create database DbTest;
286 go
287
288 use DbTest;
289 go
290
291 --创建Customers表
292 create table Customers
293 (
294 custid INT NOT NULL IDENTITY,
295 companyname NVARCHAR(40) NOT NULL,
296 country NVARCHAR(15) NOT NULL,
297 constraint pk_customer primary key(custid)
298 );
299 --创建Orders表
300 CREATE TABLE Orders
301 (
302 orderid INT NOT NULL IDENTITY,
303 custid INT NULL,
304
305 CONSTRAINT PK_Orders PRIMARY KEY(orderid),
306 CONSTRAINT FK_Orders_Customers FOREIGN KEY(custid)
307 REFERENCES Customers(custid),
308
309 );
310 set identity_insert Customers on;
311
312 INSERT INTO Customers(custid, companyname,country)
313 VALUES(1, N'大众', N'中国');
314 INSERT INTO Customers(custid, companyname,country)
315 VALUES(2, N'宝马', N'美国');
316 INSERT INTO Customers(custid, companyname,country)
317 VALUES(3, N'奔驰', N'中国');
318 INSERT INTO Customers(custid, companyname,country)
319 VALUES(4, N'奇瑞', N'德国');
320 INSERT INTO Customers(custid, companyname,country)
321 VALUES(5, N'福特', N'美国');
322
323 set identity_insert Customers off;
324 set identity_insert Orders on;
325 --custid代表员工号
326 INSERT INTO Orders(orderid, custid)
327 VALUES(1,1);
328 INSERT INTO Orders(orderid, custid)
329 VALUES(2,2);
330 INSERT INTO Orders(orderid, custid)
331 VALUES(3,3);
332 INSERT INTO Orders(orderid, custid)
333 VALUES(4,4);
334 INSERT INTO Orders(orderid, custid)
335 VALUES(5,5);
336 --查看表的数据
337 select custid,companyname,country from Customers;
338 select orderid,custid from Orders;
339 --插入数据成功
340
341 --咱们回到正题,比较Exists与in,not exists与 not in
342
343 --查询来自中国,而且下过订单的所有客户
344 select custid,companyname
345 from Customers as C
346 where country=N'中国'
347 and exists (select * from Orders as O where O.custid=C.custid);
348 --返回
349 --custid companyname
350 --1 大众
351 --3 奔驰
352
353 --外部查询返回来自中国的客户信息,对于这个客户,exists谓词在Orders表查找是否至少存在一个与外部客户行信息相同的custid订单行
354
355 --用IN查询刚刚的需求
356 select custid,companyname
357 from Customers as C
358 where country=N'中国'
359 and custid in(select custid from Orders);
360 --结果跟上面的返回一样的值
361
362 --下面的知识点我们需要认识到:
363 --当列表中有NULL时,in实际会产生一个UNKNOWN的结果,例如 a in(d,b,null)的结果是UNKNOWN,而a not in (d,b,null)返回的是not unknowd仍然是unknowd
364 --而not in与not exists则结果会很不同,例如a in(a,b,null)返回的是TRUE,而a not in(a,b,null)返回的肯定是not true即为false
365 --有了上面的认识,好继续开工了....
366 --我们现在向Orders表插入一行数据(6,null)
367 set identity_insert Orders on;
368
369 insert into Orders(orderid,custid) values(6,null);
370
371 set identity_insert Orders off;
372
373 set identity_insert Customers on;
374
375 insert into Customers(custid,companyname,country) values(7,N'雷克萨斯',N'美国');
376
377 set identity_insert Customers off;
378
379 select * from Orders;
380 select * from Customers;
381
382 --合并字符串
383 select ','+companyname from Customers where country=N'中国'
384 for xml path('')
385
386
387 --假设现在要返回来自美国且没有订单的客户
388 select custid,companyname
389 from Customers as C
390 where country=N'美国'
391 and not exists (select * from Orders as O where O.custid=C.custid );
392 --返回
393 --custid companyname
394 --7 雷克萨斯
395
396 --我们再用IN方法
397 select custid,companyname
398 from Customers as C
399 where country=N'美国'
400 and custid not in(select custid from Orders);
401 --返回的结果为空!!!
402 --为什么呢??
403 --因为还记得我们刚插入的一行数据中custid为null么,这就是问题所在
404 --not in (select custid from Orders)返回的实际是unknown,所以返回结果集为空,除非你显示的规定custid不能为空
405
406 --下面是正确的解决方法
407 select custid,companyname
408 from Customers as C
409 where country=N'美国'
410 and custid not in (select custid from Orders where custid is not null);
411 --返回
412 --custid companyname
413 --7 雷克萨斯
414
415 --所以在含有NULL值的列的时候,就要小心了,not exists与not in在逻辑上是不等价的
416 use tempdb
417 go
418 if object_id('dbo.sales') is not null
419 drop table dbo.sales;
420 go
421 --无法绑定由多个部分组成的标识符 "dbo.sales"?
422 create table sales
423 (
424 empid varchar(10) not null primary key,
425 mgrid varchar(10) not null,
426 qty int not null
427 )
428
429 delete from sales;
430 insert into sales(empid,mgrid,qty)
431 select
432 'B','X',''
433 union
434 select
435 'C','Z',''
436 union
437 select
438 'D','X',''
439 union
440 select
441 'E','Z',''
442 union
443 select
444 'F','Y',''
445 union
446 select
447 'G','Y',''
448 union
449 select
450 'H','Z',''
451 union
452 select
453 'I','Y',''
454 union
455 select
456 'J','Z',''
457 union
458 select
459 'K','Z','';
460
461
462 select * from sales;
463 --row_number()函数编号
464 select empid,qty,mgrid,
465 row_number() over ( partition by mgrid order by qty) as rowrank
466 from sales
467 order by qty;
468
469 --用基本方法计算行号(列的值不为NULL)
470 select empid,(select count(*) from sales s where s.empid<ss.empid)+1 as rowrank from sales ss order by empid;
471
472 --更新某列的值为null
473 update sales set empid=null where empid=N'F';
474
475 --select 字段 into 表 from 表
476 use tempdb;
477 if object_id('tempdb..#myshippers') is not null
478 drop table #myshippers;
479 select shipperid,companyname,phone
480 into #myshippers
481 from InsideTSQL2008.sales.shippers;
482
483 --如果需要为某个表创建应急的空副本,使用select into 很容易就可以得到它,只需提交以下语句
484 select * into target_table from source_table where 1=2;
485 --创建名为MyOrders的表
486 select *
487 into MyOrders
488 from InsideTSQL2008.sales.orders
489 where 1=2;
490
491 --OUTPUT子句
492 --支持output子句有INSERT,DELETE,UPDATE,MERGE,可以引用特殊的inserted,deleted表
493 --SCOPE_IDENTITY()函数可以返回当前范围内会话最后生成的标识值
494 --@@IDENTITY 中包含语句生成的最后一个标识值,如果语句未影响任何包含标识列的表,则 @@IDENTITY 返回 NULL
495 --
496 use tempdb;
497 if object_id('CustomersDim') is not null drop table CustomersDim;
498 go
499 create table CustomersDim
500 (
501 keycol int not null identity primary key,
502 custid int not null,
503 companyname nvarchar(40) not null
504 )
505 --@@rowcount返回受上一语句影响的行数。 如果行数大于 20 亿,请使用 ROWCOUNT_BIG
506 --声明一个表变量
507 declare @NewCusts table
508 (
509 custid int not null primary key,
510 keycol int not null unique
511 )
512 insert into CustomersDim(Custid,companyname)
513 output inserted.custid,inserted.keycol
514 into @NewCusts--表变量
515 --output inserted.custid,inserted.keycol
516 select custid,companyname
517 from InsideTSQL2008.Sales.Customers
518 where country=N'UK';
519
520 select * from @NewCusts;
521 select @@identity ;
522 --谨慎使用,现在我们想下,假设上面表 A 和表 B 都有IDENTITY自增域,那么我们在表 A 插入一条数据后,
523 --使用了 SELECT @@IDENTITY 输出时,输出的到底是 A 还是 B 的自增域的值呢?
524 --答案很明显,是谁最后插入就输出谁,那么就是 B 了。
525 --于是,我本意是想得到 A 的自增域值,结果得到了 B 的自增域值,一只 BUG 随之诞生,搞不好还会影响到整个系统数据的混乱。
526 --因此,对于这种情况,建议大家慎用 @@IDENTITY,而尽量采用 SCOPE_IDENTITY() 函数替换之。SCOPE_IDENTITY() 也是得到最后一条自增域的值,
527 --但是它是仅限在一个操作范围之内,而@@IDENTITY 是取全局操作的最后一步操作所产生的自增域的值的。
528 select scope_identity();
529
530
531 --从表中删除大量数据,并避免日志爆炸式增长和锁升级
532 --假如要删除2006年之前所有订单
533 --那我们采取分批方法,每次删除5000行
534 while 1=1
535 begin
536 delete top(5000) from LargeOrders where orderdate<'';
537 if(@@rowcount<5000) break;--如果没有5000行,则循环一次就跳出循环
538 end;
539
540 --返回一个随机的数
541 --select N'随机'+right('000000000'+cast(1+ abs(checksum(newid())) as varchar(10)),10) as 随机值;
542
543 --5分钟内向某表随机插入值
544 use tempdb;
545 if object_id('randtable') is not null drop table randtable;
546 go
547 create table randtable
548 (
549 ID int not null identity primary key,
550 msg varchar(max) not null
551 )
552
553 declare @msg as varchar(max);
554 declare @now as datetime;
555 set @now=current_timestamp;
556 while 1=1 and datediff(second,@now,current_timestamp)<300
557 begin
558 set @msg=N'随机'+right(''+cast(1+ abs(checksum(newid())) as varchar(10)),10);
559 insert into randtable(msg) values (@msg);
560 end
561 --select @@rowcount--返回影响行数
562
563 select * from randtable;
564 select (max(ID)-min(ID)) as N'总行数' from randtable;
565 select max(ID)as N'最大ID' from randtable;--
566 select min(ID) as N'最小ID'from randtable;--
567
568 --比较几种删除数据的执行效率
569 --我们一分钟内随机插入数据
570 delete from randtable;--用这种直接删除数据方式,删除415850条数据 用时52秒:
571
572 --删除5686094条数据 用时29秒;
573 --删除7679924条数据 用时19秒;
574 --删除11248379条数据 用时2秒;
575 --删除10803495条数据 用时2秒;
576
577 --下面我们采取另一种方式删除,即分批删除
578 while 1=1
579 begin
580 delete top(5000) from randtable --where ID<19061681;
581 --if(@@rowcount<5000) break;--如果没有5000行,则循环一次就跳出循环
582 end;
583
584 --比较现在时间与之后之间的差值
585 datediff(second,@now,current_timestamp);
586
587 --更新表结构
588 alter table tablename
589 add constraint pk_name primary key(columnname);
590
591
592 --将空值转换为实际值
593 --coalesce(comm,0)
594 --与COALESCE(expression1,...n) 的功能与以下 CASE 表达式相同:
595 --
596 --CASE
597 --
598 -- WHEN (expression1 IS NOT NULL) THEN expression1
599 --
600 -- WHEN (expression2 IS NOT NULL) THEN expression2
601 --
602 -- ...
603 --
604 -- ELSE expressionN
605 --
606 --END 类似
607
608 --利用case指定order by的列动态排序
609 select ename,sal,job,comm
610 case when job='saleman' then comm else sal end as ordered
611 from emp
612 order by 5;
613
614 --UNION ALL(包括重复行)
615 --将多个来源的行组合起来,放到一个结果集,所有select列表的项目数
616 --和对应项目的数据类型必须要匹配
617
618 --UNION(不包括重复行)
619
620 --创建数字辅助表(Nums)
621 if object_id('Nums') is not null drop table Nums;
622 go
623 create table Nums(n int not null primary key);
624 declare
625 @max as int,
626 @rc as int;
627 set @max=10000;
628 set @rc=1;
629 insert into Nums values(1);
630 while @rc*2<=@max
631 begin
632 insert into Nums select n+@rc from Nums;
633 set @rc=@rc*2;
634 end
635 insert into Nums
636 select n+@rc from Nums where n+@rc<=@max;
637
638 -- 创建一个“天”表,把Customers表与Employees表生成雇员-客户-每天组合
639 select custid,empid,dateadd(day,n-1,'') as orderdate ,row_number() over (order by (select 0))as orderid
640 from sales.customers
641 cross join HR.employees
642 cross join Nums
643 where n<31;
644
645 --对于每个订单,计算订单价格占总价格的百分比,以及它与所有订单平均价格的差额
646 drop table Myordervalues
647 select * into MyorderValues
648 from sales.Ordervalues;
649
650 alter table myordervalues
651 add constraint pk_myordervalues primary key (orderid);
652 create index idx_val on myordervalues(val);
653
654 select orderid,custid,val ,cast(val/(select sum(val) from myordervalues)*100 as numeric(5,2)) as pct,
655 cast(val-(select avg(val) from myordervalues)*100 as numeric(12,2)) as diff
656 from myordervalues;
657
658 --内联结(inner)
659 --关于ON与where,如果一个查询既包含ON,又要包含where字句,逻辑上他们会依次应用,除了一个
660 --外,在Inner Join的on字句中指定逻辑表达式,还是在where字句中指定逻辑表达式,没有任何区别,因为
661 --两个步骤没有中间步骤会添加外部行。
662 --这个例外,就是当指定了group by all选项时,group by all会把where字句过滤掉的组再添加到结果集
663 --但不会添加ON字句过滤掉的组。
664
665 --如何规范的去放置逻辑条件呢?
666 --参考:把表之间匹配属性的筛选器应该位于ON字句中,而只对一个表的属性进行筛选的筛选器应该位于在where字句中
667 --例如:
668 select c.custid,companyname,orderid from sales.customers as c,sales.orders as o on c.custid=o.custid and country=N'USA';
669
670 --外联接(OUTER)
671 --外联接用于返回两个表中按一定条件匹配的行,以及“保留”表中不能被匹配的行
672 --可以用left,right,full,关键字保留表,left把坐标标记为保留表,right把右表标记为保留表,full把两个表都标记为保留表
673 --外联接有三个阶段:笛卡尔积-》ON筛选器-》添加外部行,对于保留表中未找到匹配的行,将作为外部行添加到结果集,并用
674 --null作为相应非保留表属性的取值
675
676 --以下查询返回客户及其订单ID
677 select c.custid,o.orderid into #tb
678 from sales.Customers as c
679 left outer join sales.orders as o
680 on c.custid=o.custid;
681 --返回订单是NULL的客户行
682 select* from #tb where orderid is null;
683
684 --关键字outer是可选的,因为使用left,right,full就隐含着这是一个外联接,通常使用
685 --内联接不加关键字inner,而使用外联接通常加上关键字outer
686
687
688 --其他联接
689 --自联接(是在同一个表的两个实例之间进行的联接)
690 --以下是一个简单的自联接例子,对Employees表的两个实例进行联接,一个代表雇员(E),另一个代表经理(M)
691 --当联接同一个表的两个实例时,必须至少为其中一个表应用别名,为每一个实例,提供惟一的一个名称
692 select E.firstname,E.lastname as emp,
693 M.firstname,M.lastname as mgr
694 from HR.Employees as E left outer join HR.Employees as M
695 on E.mgrid=M.empid;
696
697 --不等联接
698 --等值联接是联接条件基于等号(=)运算符的联接,不等联接的联接条件中包含的是除等号以外的其他运算符
699
700 --存储过程
701 --o(∩_∩)o ,终于到存储过程这一环节了,不容易啊....
702 --存储过程是把一个或多个T-SQL语句组合到一个逻辑单元,在sqls中保存为一个对象,当首次执行时,sqlserver创建执行计划
703 --并把它存在计划内缓存中,然后进行重用,重用计划使得存储过程提供了可靠的性能
704 --优点:
705 --(1)提升应用程序的可支持性
706 --(2)减少网络流量
707 --(3)促进代码可复用性
708 --(4)淡化数据的获取方式
709 --(5)查询时间比较稳定
710 --(6)有效防止SQL Injection
711 --(7)能作为控制层,控制一定的权限
712
713 --基本语法
714 --没有参数的存储过程
715 --create procedure [schema_name.] procedure_name--是架构和存储过程的名字
716 --as {<sql_statement>[...n]}--主体
717 --创建一个查询master数据库的存储过程
718 use master
719 go
720 create procedure select_master
721 as
722 select * from spt_values;
723 go
724 --执行存储过程
725 exec select_master;--不需要加exec procedure proc_name
726 --go关键字用于标记存储过程结束
727 --在创建存储过程的时候,会检查sql语法的正确性,不会去检查引用表是否存在,这意味着你可能引用了不存在
728 --的表,并且直到运行的时候才报错,这叫做延迟名称解析
729
730 --创建带参数的存储过程,一个存储过程可以传入2100个参数
731 --语法如下
732 --create {proc|procedure} [schema_name] procedure_name[;number]
733 --[{@parameter[type_shacema_name.]data_type}[varying][=default][out|output][readonly]][,...n]
734 --[with <procedure_option>[,...n]]
735 --[for replaction]
736 --as {<sql_statement>[;][...n]|<method_specifier>}
737 --参数以@为前缀后面是参数的数据类型和可选的默认值
738 --
739 create procedure shoppingitem
740 (@shoppingcartid nvarchar(50),
741 @quantity int =1,
742 @productid int)
743 as
744 if exists(select * from Sales.ShoppingCartItem
745 where shoopingcartid=@shoppingcartid
746 and productid=@productid)
747
748 begin
749 update sale.shoppingcartitem
750 set quantity=@quantity
751 where shoppingcartid=@shoppingcartid and productid=@productid
752 print'updated....'
753 end
754
755 else
756 begin
757 insert sale.shoppingcartitem(shoppingcartid,productid,quantity)values (@shoppingcartid,@productid,@quantity)
758 print 'inserted.....'
759 end
760 go
761 --执行,传入三个参数
762 exec shoppingitem '',2,316
763
764 --output参数
765 --该参数是把信息返回给存储过程调用者,无论是另外的存储过程或即席调用(嵌入程序中sql语句)
766 --例子
767 --创建一个返回某个组的部门列表
768 create procedure seldepartment
769 @groupname nvarchar(50),
770 @deptcount int putput
771 as
772 select [name]
773 from hr.department
774 where groupname=@groupname
775 order by [name]
776 select @deptcount=@@rowcount
777 go
778 --执行
779 declare @deptcount int
780 exec deldepartment 'hr',@deptcount output
781 --更新存储过程
782 alter procedure ....
783 --删除存储过程
784 drop procedure ....
785
786 --创建自动执行的存储过程
787 --每当重启sql时,自动向一张表中插入重启的时间
788 use master
789 go
790 create table sqlstartlog
791 (
792 startid int identity(1,1) primary key not null,
793 startdatetime datetime not null
794 )
795 go
796 --创建一个存储过程向表中插入值
797 create procedure insertstartlog
798 as
799 insert sqlstartlog(startdatetime) values(getdate())
800 go
801 --设置自动执行的存储过程
802 exec sp_procoption @ProcName='insertstartlog',@OptionName='startup',@OptionValue='true';
803 --重启后,查看insertstartlog
804 select * from sqlstartlog;
805 --如果需要禁用
806 exec sp_procoption @ProcName='insertstartlog',@OptionName='startup',@OptionValue='false';
807 --在这个更总sql server启动的例子中,存储过程必须创建在master数据库中
808
809 --加密
810 --只需要在创建存储过程的名字后面加入with encryption
811 --查看存过程
812 alter procedure sampleencryption
813 with encryption
814 as
815 set nocount on--使不提示受T-SQL语句影响的行数,@@rowcount不受其影响
816 select * from sqlstartlog
817 go
818 --
819 exec sp_helptext sampleencryption;
820
821 --使用execute as来指定过程的安全上下文
822 --with execute as 关键字允许你指定存储过程执行所在的安全上下文,覆盖存储过程调用者的默认安全
823
824 --概念:权链
825 --当创建一个对象(例如存储过程,或者视图),并将其用来对另外一个数据库对象进行Insert,Delete,Select,Update对象的时候
826 --就出现了“所有权链”,如果存储过程对象的架构和它引用对象的架构一样,sqlserver只会检查存储过程调用者是否有对存储过程execute的
827 --权限
828
829 --重新编译与缓存
830 --存储过程的性能优势主要是在重用计划
831
832 --当存储过程的计划自动或先是重建的时候就会发生重新编译,当存储过程中引用的基础表或其他对象
833 --发生变化后,存储过程就会在其执行期间自动重新编译。计划使用的索引发生变动或者存储过程引用的表键发生了大量的更新也可能引起重新编译
834 --sql server存储过程使用的是语句级别的重新编译,能够减小负载。
835
836 --查询缓存数量
837 select count(*) 'CachedPlansBefore'
838 from sys.dm_exec_cached_plans;
839 --清空缓存
840 dbcc freeproccache;
841
842 --注意事项
843 --不能在一个存储过程中删除另一个存储过程,只能调用另一个存储过程
844
845 --存储过程常用命令
846 --显示所有存储过程的基本信息
847 show procedure status;
848
849
850
851 -- 显示使用的时间
852 declare @BeginDate datetime
853 set @BeginDate=getdate();
854 begin
855
856 end
857
858 SELECT BeginDate = @dt, EndDate = GETDATE(),
859 Second = DATEDIFF(Second, @dt, GETDATE());
860
861 --生成多少万条不重复的n位数字
862 use tempdb
863 go
864
865 --创建测试表
866 create table testtable(id char(8) );
867
868 --创建用于自动过滤重复值的唯一索引
869 create unique index ui_tb on testtable(id)
870 with IGNORE_DUP_KEY
871 go
872 --测试数据插入的时间
873 declare @dt datetime
874 set @dt=getdate()
875 set nocount on;
876 declare @row int
877 set @row=100000
878 while @row>0
879 begin
880 raiserror('need %d rows',10,1,@row) with nowait
881 set rowcount @row
882 insert testtable select id=right(100000000+convert(bigint,abs(checksum(newid()))),8)
883 from syscolumns c1,syscolumns c2--syscolumns为每个表和视图中的每列返回一行,并为数据库中的存储过程的每个参数返回一行。
884 set @row=@row-@@rowcount;
885 end
886 select BeginDate=@dt,EndDate=getdate(),Second=datediff(Second,@dt,getdate())
887 go
888 drop table testtable;
889
890 ---------------------------------------------------
891 use tempdb
892 go
893
894 --我写的这种只有5秒左右时间,而上面却有40几秒
895 --创建测试表
896 create table testtable(id int identity(1,1) not null,num char(8) );
897
898 --创建用于自动过滤重复值的唯一索引
899 create unique index ui_tb on testtable(num)
900 with IGNORE_DUP_KEY
901 go
902 --测试数据插入的时间
903 declare @dt datetime
904 set @dt=getdate()
905 set nocount on;
906 declare @row int
907 set @row=100000
908 declare @xx char(8)
909 while @row>0
910 begin
911 set @xx=right(100000000+convert(bigint,abs(checksum(newid()))),8);
912 --print @xx;
913 insert testtable(num) values(@xx)
914 set @row=@row-@@rowcount;
915 end
916 select BeginDate=@dt,EndDate=getdate(),Second=datediff(Second,@dt,getdate())
917 select count(*) from testtable;
918 go
919 drop table testtable;
920
921 select * from dbo.testtable
922
923 --这是第二次温习not in与exists ,not exists了
924 use tempdb;
925 go
926 if object_id(N'test') is not null
927 drop table test
928 create table test
929 (
930 ID int not null identity(1,1) primary key,
931 depno char(10)
932 )
933 insert into test(depno) values(20);
934 insert into test(depno) values (10);
935 insert into test(depno) values(40);
936 insert into test(depno) values (30);
937 insert into test(depno) values (null);
938
939 create table test2
940 (
941 ID int not null identity(1,1) primary key,
942 depno char(10)
943 )
944 insert into test2(depno) values(10);
945 insert into test2(depno) values (100);
946 insert into test2(depno) values (20);
947
948 select * from test;
949 select * from test2;
950
951 select t.depno from test t where t.depno not in (select t2.depno from test2 t2 )
952
953 --下面查询查不到任何值,因为子查询中depno含有null值,并且是用not in判断
954 select t2.depno from test2 t2 where t2.depno not in (select t.depno from test t )
955 --采用exists
956 select t2.depno from test2 t2 where not exists (select null from test t where t.depno=t2.depno )
957
958 ESCAPE
959 --如果要以文本的形式搜索,而不是被sql解释为通配符,可以使用escape关键字
960 where description like '%/%%' escape '/'--搜索与“%”匹配的
961 create table a (name varchar(10))
962 go
963 insert into a select '11%22'
964 union all select '11%33'
965 union all select '12%33'
966 go
967 select * from a WHERE name LIKE '%/%33' ESCAPE '/' --指定用'/'符号来说明跟在其后面的通配符字符为普能字符。(第二个%是字符不是通配符来的)
968 go
969 drop table a
970 --结果为:
971 -- name
972 ----------
973 -- 11%33
974 -- 12%33
975 --再来一个
976 SELECT * FROM finances WHERE description LIKE 'gs_' ESCAPE 's'
977 --意思就是: 比如,我们要搜索一个字符串 "g_" ,如果直接 like "g_",那么 "_"的作用就是通配符,而不是字符,结果,我们会查到比如 "ga","gb","gc",而不是我们需要的 "g_". 用 LIKE 'gs_' ESCAPE 'S' 's'表示特殊用法标志
978
979 --声明变量
980 --在sql2005不允许声明变量后紧接着就赋值
981 --而在sql2008可以省略set关键字直接赋值
982 use InsideTSQL2008
983 go
984 select top 10percent * from MyorderValues;--返回10%的行
985
986 --建议
987 --避免使用不兼容的数据类型。例如float和int、char和varchar、binary和
988 --varbinary是不兼容的
989 --避免使用不兼容的数据类型。例如float和int、char和varchar、binary和
990 --varbinary是不兼容的。数据类型的不兼容可能使优化器无法执行一些本来可以进
991 --行的优化操作。例如:
992 SELECT name FROM employee WHERE salary >60000
993 --在这条语句中,如salary字段是money型的,则优化器很难对其进行优化,因为60000
994 --是个整型数。我们应当在编程时将整型转化成为货币型,而不要等到运行时转化。
995
996 --尽量避免在WHERE子句中对字段进行函数或表达式操作,这将导致引擎放弃
997 --使用索引而进行全表扫描。如:
998 SELECT * FROM T1 WHERE F1/2=100
999 --应改为:
1000 SELECT * FROM T1 WHERE F1=100*2
1001
1002 SELECT * FROM RECORD WHERE SUBSTRING(CARD_NO,1,4)=’5378’
1003 --应改为:
1004 SELECT * FROM RECORD WHERE CARD_NO LIKE ‘5378%’
1005
1006 SELECT member_number, first_name, last_name FROM members
1007 WHERE DATEDIFF(yy,datofbirth,GETDATE()) > 21
1008 --应改为:
1009 SELECT member_number, first_name, last_name FROM members
1010 WHERE dateofbirth < DATEADD(yy,-21,GETDATE())
1011 --即:任何对列的操作都将导致表扫描,它包括数据库函数、计算表达式等等,查询
1012 --时要尽可能将操作移至等号右边。
1013
1014 --尽量使用数字型字段,一部分开发人员和数据库管理人员喜欢把包含数值信
1015 --息的字段
1016 --设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在
1017 --处理查询和连接回逐个比较字符串中每一个字符,而对于数字型而言只需要比较一
1018 --次就够了。
1019
1020 --创建用','分隔的列表
1021 select * from nums
1022 declare @splitstring nvarchar(50)
1023 set @splitstring='';
1024 select @splitstring=@splitstring+convert(char(2),n)+','--因为n是数值型,需要转换,不然就是求和了
1025 from Nums
1026 where n<15;
1027 select @splitstring;
1028
1029 --select into到临时表
1030 select n into #tempdb
1031 from nums;
1032 select * from #tempdb;
1033
1034 --在频繁执行的查询中,发生隐式转换,将会非常影响性能例如nchar转为char
1035
1036 --复习索引
1037 --索引是在表上创建的数据库对象,它可以提供到数据更快的访问,并且可以使查询执行更快
1038 --sql中,存储单位最小的是页,页是不可再分的,换句话说,要么整个读取,要么不读
1039 --如果表上没有索引,那么就是存放在堆Heap中,即使你想找的数据就是第一项,那么sql引擎也需要进行全表扫描
1040 --对于数据库检索来说,对于磁盘的IO是最消耗时间的
1041
1042 --测试sql IO次数
1043 use tempdb
1044 go
1045 create table testio
1046 (
1047 id int,
1048 c1 int,
1049 c2 int,
1050 c3 int,
1051 c4 char(2)
1052 )
1053 insert into testio values(1,1,1,'a');
1054 insert into testio values(2,2,2,'a');
1055 insert into testio values(3,3,3,'a');
1056 insert into testio values(4,4,4,'a');
1057 insert into testio values(5,5,5,'a');
1058 insert into testio values(6,6,6,'a');
1059 insert into testio values(7,7,7,'a');
1060 insert into testio values(8,8,8,'a');
1061 insert into testio values(9,9,9,'a');
1062 insert into testio values(10,10,10,'a');
1063 insert into testio values(11,11,11,'a');
1064 insert into testio values(12,12,12,'a');
1065 insert into testio values(13,13,13,'a');
1066 insert into testio values(14,14,14,'a');
1067 insert into testio values(15,15,15,'a');
1068 insert into testio values(16,16,16,'a');
1069 insert into testio values(170,170,170,'a');
1070
1071 --开启IO数量
1072 set statistics io on;
1073 select * from testio where c1=170;
1074 --建立索引
1075 create index idx_testio on testio(c1);
1076 select * from testio where c1=170;
1077
1078
1079 use HR
1080 go
1081 select top 10(ID) from Talent_Big;
1082 select * from Talent_Big where ID=480000;
1083 --建立索引
1084 drop index idx_talent_big on Talent_Big;
1085
1086 --理解聚集和聚集索引
1087 --
1088 -- 在SQL Server中,最主要的两类索引时聚集索引和非聚集索引。可以看到,这两个分类都是围绕聚集这个关键字进行的,那么首先理解什么是聚集。
1089 --
1090 -- 聚集在索引中的定义:
1091 --
1092 -- 为了提高某个属性(或属性组)的查询速度,把这个或这些属性(成为聚集码)上具有相同值的元组集合中存放在连续的物理块成为聚集。
1093 --
1094 --非聚集索引
1095 --
1096 -- 因为每个表只能有一个聚集索引,如果我们对一个表的查询不仅仅限于聚集索引上的字段。我们又对聚集索引列之外还有索引的要求,那么就需要非聚集索引了。
1097 --
1098 -- 非聚集索引,本质上来说也是聚集索引的一种,非聚集索引并不改变其所在表的物理结构,而是额外生成一个聚集索引的B树结构,但叶节点是对于其所在表的引用,
1099 --这个引用分为两种,如果其所在表上没有聚集索引,则引用行号;如果其所在表上已经有了聚集索引,则引用聚集索引的页,从而实现更大限度的使用。
1100
1101 --随着数据量的增长,产生了索引碎片,很多存储的数据进行了不适当的跨页,会造成碎片
1102 --这时我们可以通过重建索引来提高速度:
1103
1104 ALTER INDEX idx_text_tb2_EmployeeID ON test_tb2 REBUILD
1105 --
1106 --还有一种情况是,当随着表数据量的增大,有时候需要更新表上的统计信息,让查询分析器根据这些信息选择路径,使用:
1107 --
1108 --UPDATE STATISTICS 表名
1109 --
1110 --那么什么时候知道需要更新这些统计信息呢,就是当执行计划中估计行数和实际表的行数有出入时:
1111
1112 -- 当然索引的使用也是要付出代价的:
1113 --
1114 -- 1、通过聚集索引的原理我们知道,当表建立索引后,就可以B树来存储数据,所以当对其进行更新插入删除,就需要页在物理上移动以调整B树,因此当更新插入删除数据时,会带来性能的下降。
1115 --而对于非聚集索引,当更新表后,非聚集索引需要进行更新,相当于多更新了N(N=非聚集索引数量)个表。因此也下降了性能。
1116 --
1117 -- 2、通过上面对非聚集索引原理的介绍,可以看到,非聚集索引需要额外的磁盘空间。
1118 --
1119 -- 3、前文提过,不恰当的非聚集索引反而会减低性能。
1120 --
1121 -- 所以使用索引需要根据实际情况进行权衡.通常我都会将非聚集索引全部放到另外一个独立硬盘上,这样可以分散IO,从而使查询并行.
1122
1123
1124 --视图
1125 --sql中分为3种视图
1126 --普通视图,在数据库中不保存实际数据,只是视图定义
1127 --索引视图,保存了真实的索引数据
1128 --分布式分区视图,可以用UNION ALL来把多个跨两个以上sql实例的较小的表组合成一个虚拟表
1129
1130 --select语句允许一个视图定义1024个列,然而,不可以在视图定义中使用某些select元素,包括into,option,compute,compute by 或者对
1131 --表变量或临时表的引用。除非使用了top关键字,否则也不可以使用order by
1132 --创建视图
1133 create view view_somedefin
1134 as
1135 select * from testio
1136 go
1137 --查看某个视图的定义
1138 select definition from sys.sql_modules
1139 where object_id=object_id('view_somedefin');
1140 --删除视图
1141 drop view view_somedefin;
1142 --视图加密
1143 create view view_somedefinencrypt
1144 with encryption
1145 as
1146 select * from testio;
1147 go
1148 --此时通过sys.sql_modules系统目录视图来查看该视图的definition是null
1149
1150 --使用视图修改数据
1151 --可以像普通表一样对视图进行插入,更新,删除,但是这些操作只能引用一个表中的列,而且,这些操作中引用列不能进行
1152 --衍生,例如它们不能基于聚合函数被计算或受group by ,distinct 或having子句
1153 --例子
1154 create view view_production
1155 as
1156 select ID,proname,proprice,num,num*prpprice totalcost
1157 from production
1158 go
1159 --以上创建了一个视图,现在向其中插入一条数据
1160 insert view_production (proname,proprice,num,totalcost) values ('可乐',2,10,20);
1161 --发生错误
1162 --对视图或函数’view_production‘的更新或插入失败、因其包含派生域或常量域
1163 --其实问题是出生在’totalcost‘中,它引用了两列,只要去掉插入该列的值即可
1164
1165 --创建索引视图
1166 use InsideTSQL2008
1167 go
1168 create view view_Employees
1169 with schemabinding
1170 as
1171 select E.empid ,E.lastname,E.firstname,E.title,E.address,E.city,O.orderdate,O.shipname
1172 from HR.Employees E
1173 join
1174 Sales.Orders O
1175 on O.empid=E.empid ;
1176 go
1177 --drop view view_Employees;
1178 set statistics io on;
1179 select * from view_Employees
1180 --查询完毕后,我们发现empid这列是无序的,并且Orders表的逻辑读取次数为21次,Employees的逻辑读取次数2次
1181 --因为empid为主键与外键,所以已经有了聚集索引,而一个表中只能有一个聚集索引,所以为视图创建非聚集索引
1182 create nonclustered index uci_index_Employees_Orders
1183 on Sales.Orders(orderdate)
1184 go
1185 --删除索引
1186 drop index Sales.Orders.uci_index_Employees_Orders;
一些我 不常用到的SQL
1 --------添加链接服务器
2 EXEC sp_addlinkedserver 'MyDBServer','','MSDASQL',NULL,NULL,
3 'DRIVER={SQL Server};SERVER=192.168.1.254,1234;UID=sa;PWD=1234568@abc;'
4
5
6 select * from MyDBServer.Hisense_MobileSales.dbo.sales
7
8 Exec sp_droplinkedsrvlogin DBVIP,Null --删除映射(录与链接服务器上远程登录之间的映射)
9 exec sp_dropserver 'DBVIP' --删除链接
10
11 EXEC sp_addlinkedserver
12 @server='DBVIP',--被访问的服务器别名
13 @srvproduct='',
14 @provider='SQLOLEDB',
15 @datasrc="DRIVER={SQL Server};SERVER=192.168.1.254,1234;UID=sa;PWD=1234568@abc;" --要访问的服务器
16
17
18 EXEC sp_addlinkedsrvlogin
19 'DBVIP', --被访问的服务器别名
20 'false',
21 NULL,
22 'sa', --帐号
23 'thankyoubobby' --密码
24 Select * from DBVIP.Hisense_MobileSales.dbo.city
25
26
27
28 ----修改密码成功
29 EXEC sp_password null,"123456","sa"
30 go
31 Alter LOGIN sa ENABLE
1 ---2005附加数据库
2 ---ATTACH DATABASE TEMPLATE
3 exec sp_attach_db 'ghpTest','C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\ghpTest.mdf',
4 'C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\ghpTest_log.ldf'
5 GO
6 ---分离数据库
7 use ghpTest
8 go
9 exec sp_detach_db @dbname ='ghpTest'
10 go
11 ---列出存储过程
12 exec sp_stored_procedures
13 GO
14 --系统视图
15 select * from sys.objects
16
17 ---列出存储过程
18 select * from sys.objects WHERE TYPE='P'
19 select [name] from sysobjects where xtype='P' order by [name]
20 GO
21 ---列出所有表
22 select * from sys.objects WHERE TYPE='U' order by [name]
23 select [name] from sysobjects where xtype='U' order by [name]
24 GO
25 --列出视图
26 select * from sys.objects WHERE TYPE='V' order by [name]
27 select [name] from sysobjects where xtype='V' order by [name]
28 GO
29 --
30 select * from sysobjects
31 GO
32 --查詢数据库中的表所占用空间
33 exec sp_spaceused '表名' --取得表占用空间
34 exec sp_spaceused 'Province'
35 exec sp_spaceused --数据库所有空间
36
37
38 ---1 方式
39 create table #Data(name varchar(100),row varchar(100),reserved varchar(100),data varchar(100),index_size varchar(100),unused varchar(100))
40 GO
41 declare @name varchar(100)
42 declare cur cursor for
43 select name from sysobjects where xtype='u' order by name
44 open cur
45 fetch next from cur into @name
46 while @@fetch_status=0
47 begin
48 insert into #data
49 exec sp_spaceused @name
50 print @name
51
52 fetch next from cur into @name
53 end
54 close cur
55 deallocate cur
56 go
57 select * from #Data
58 GO
59 ---2 方式
60 create table #DataNew(name varchar(100),row int,reserved int,data int,index_size int,unused int)
61 GO
62 insert into #dataNew
63 select name,convert(int,row) as row,convert(int,replace(reserved,'KB','')) as reserved,convert(int,replace(data,'KB','')) as data,
64 convert(int,replace(index_size,'KB','')) as index_size,convert(int,replace(unused,'KB','')) as unused from #data
65 GO
66 select * from #dataNew order by data desc
67 GO
68 ---数据库对象限定符:
69 --[[[server.][database].][schema].]database_object
70 ---schema dbo(默認模式)
71
72 /*
73
74 使用完毕后,记得一定要要关闭它,因为这是一个安全隐患,切记执行下面的SQL语句
75
76 --创建链接服务器
77 exec sp_addlinkedserver 'ITSV ', ' ', 'SQLOLEDB ', '远程服务器名或ip地址 '
78 exec sp_addlinkedsrvlogin 'ITSV ', 'false ',null, '用户名 ', '密码 '
79
80 --查询示例
81 select * from ITSV.数据库名.dbo.表名
82
83 --导入示例
84 select * into 表 from ITSV.数据库名.dbo.表名
85
86 --以后不再使用时删除链接服务器
87 exec sp_dropserver 'ITSV ', 'droplogins '
88
89 --连接远程/局域网数据(openrowset/openquery/opendatasource)
90 --1、openrowset
91
92 --查询示例
93 select * from openrowset( 'SQLOLEDB ', 'sql服务器名 '; '用户名 '; '密码 ',数据库名.dbo.表名)
94
95 --生成本地表
96 select * into 表 from openrowset( 'SQLOLEDB ', 'sql服务器名 '; '用户名 '; '密码 ',数据库名.dbo.表名)
97
98 --把本地表导入远程表
99 insert openrowset( 'SQLOLEDB ', 'sql服务器名 '; '用户名 '; '密码 ',数据库名.dbo.表名)
100 select *from 本地表
101
102 --更新本地表
103 update b
104 set b.列A=a.列A
105 from openrowset( 'SQLOLEDB ', 'sql服务器名 '; '用户名 '; '密码 ',数据库名.dbo.表名)as a inner join 本地表 b
106 on a.column1=b.column1
107
108 --openquery用法需要创建一个连接
109
110 --首先创建一个连接创建链接服务器
111 exec sp_addlinkedserver 'ITSV ', ' ', 'SQLOLEDB ', '远程服务器名或ip地址 '
112 --查询
113 select *
114 FROM openquery(ITSV, 'SELECT * FROM 数据库.dbo.表名 ')
115 --把本地表导入远程表
116 insert openquery(ITSV, 'SELECT * FROM 数据库.dbo.表名 ')
117 select * from 本地表
118 --更新本地表
119 update b
120 set b.列B=a.列B
121 FROM openquery(ITSV, 'SELECT * FROM 数据库.dbo.表名 ') as a
122 inner join 本地表 b on a.列A=b.列A
123
124 --3、opendatasource/openrowset
125 SELECT *
126 FROM opendatasource( 'SQLOLEDB ', 'Data Source=ip/ServerName;User ID=登陆名;Password=密码 ' ).test.dbo.roy_ta
127 --把本地表导入远程表
128 insert opendatasource( 'SQLOLEDB ', 'Data Source=ip/ServerName;User ID=登陆名;Password=密码 ').数据库.dbo.表名
129 select * from 本地表
130
131 */
132
133
134 --2005 启用Ad Hoc Distributed Queries的方法,执行下面的查询语句就可以了:
135 exec sp_configure 'show advanced options',1
136 reconfigure
137 exec sp_configure 'Ad Hoc Distributed Queries',1
138 reconfigure
139 --使用完毕后,记得一定要要关闭它,因为这是一个安全隐患,切记执行下面的SQL语句
140 exec sp_configure 'Ad Hoc Distributed Queries',0
141 reconfigure
142 exec sp_configure 'show advanced options',0
143 reconfigure
144
145 --
146 SELECT top 10 * FROM OPENDATASOURCE('SQLOLEDB','Data Source=.;User ID=sa;Password=geovindu;').geovinduDB.dbo.meetingApply
147 GO
148
149 --openrowset使用OLEDB的一些例子
150 select * from openrowset('SQLOLEDB','Server=(local);PWD=***;UID=sa;','select * from GEOVINDU.dbo.school') as t
151 select * from openrowset('SQLOLEDB','Server=(local);PWD=***;UID=sa;',GEOVINDU.dbo.school) as t
152 select * from openrowset('SQLOLEDB','Server=(local);Trusted_Connection=yes;',GEOVINDU.dbo.school) as t
153 select * from openrowset('SQLOLEDB','(local)';'sa';'***','select * from GEOVINDU.dbo.school') as t
154 select * from openrowset('SQLOLEDB','(local)';'sa';'***',GEOVINDU.dbo.school) as t
155 select * from openrowset('SQLOLEDB','(local)';'sa';'***','select school.id as id1,people.id as id2 from GEOVINDU.dbo.school inner join GEOVINDU.dbo.people on school.id=people.id') as t
156
157 --openrowset使用SQLNCLI的一些例子(SQLNCLI在SqlServer2005以上才能使用)
158 select * from openrowset('SQLNCLI','(local)';'sa';'***','select * from GEOVINDU.dbo.school') as t
159 select * from openrowset('SQLNCLI','Server=(local);Trusted_Connection=yes;','select * from GEOVINDU.dbo.school') as t
160 select * from openrowset('SQLNCLI','Server=(local);UID=sa;PWD=***;','select * from GEOVINDU.dbo.school') as t
161 select * from openrowset('SQLNCLI','Server=(local);UID=sa;PWD=***;',GEOVINDU.dbo.school) as t
162 select * from openrowset('SQLNCLI','Server=(local);UID=sa;PWD=***;DataBase=GEOVINDU','select * from dbo.school') as t
163
164 --openrowset其他使用
165 insert openrowset('SQLNCLI','Server=(local);Trusted_Connection=yes;','select name from GEOVINDU.dbo.school where id=1') values('geovindu')/*要不要where都一样,插入一行*/
166 update openrowset('SQLNCLI','Server=(local);Trusted_Connection=yes;','select name from GEOVINDU.dbo.school where id=1') set name='geovindu'
167 delete from openrowset('SQLNCLI','Server=(local);Trusted_Connection=yes;','select name from GEOVINDU.dbo.school where id=1')
168
169
170
171
172
173 --opendatasource使用SQLNCLI的一些例子
174 select * from opendatasource('SQLNCLI','Server=(local);UID=sa;PWD=***;').GEOVINDU.dbo.school as t
175 select * from opendatasource('SQLNCLI','Server=(local);UID=sa;PWD=***;DataBase=TB').GEOVINDU.dbo.school as t
176
177 --opendatasource使用OLEDB的例子
178 select * from opendatasource('SQLOLEDB','Server=(local);Trusted_Connection=yes;').GEOVINDU.dbo.school as t
179
180 --opendatasource其他使用
181 insert opendatasource('SQLNCLI','Server=(local);Trusted_Connection=yes;').GEOVINDU.dbo.school(name) values('geovindu')/*要不要where都一样,插入一行*/
182 update opendatasource('SQLNCLI','Server=(local);Trusted_Connection=yes;').GEOVINDU.dbo.school set name='geovindu'
183 delete from opendatasource('SQLNCLI','Server=(local);Trusted_Connection=yes;').GEOVINDU.dbo.school where id=1
184
185
186
187
188
189 --openquery使用OLEDB的一些例子
190 exec sp_addlinkedserver 'ITSV', '', 'SQLOLEDB','(local)'
191 exec sp_addlinkedsrvlogin 'ITSV', 'false',null, 'sa', '***'
192 select * FROM openquery(ITSV, 'SELECT * FROM GEOVINDU.dbo.school ')
193
194 --openquery使用SQLNCLI的一些例子
195 exec sp_addlinkedserver 'ITSVA', '', 'SQLNCLI','(local)'
196 exec sp_addlinkedsrvlogin 'ITSVA', 'false',null, 'sa', '***'
197 select * FROM openquery(ITSVA, 'SELECT * FROM GEOVINDU.dbo.school ')
198
199 --openquery其他使用
200 insert openquery(ITSVA,'select name from GEOVINDU.dbo.school where id=1') values('geovindu')/*要不要where都一样,插入一行*/
201 update openquery(ITSVA,'select name from GEOVINDU.dbo.school where id=1') set name='geovindu'
202 delete openquery(ITSVA,'select name from GEOVINDU.dbo.school where id=1')
203
204
205 backup database intranet to disk='C:\ba.bak' with init
206
207
208 RESTORE DATABASE nwind_new FROM DISK = 'c:\backups\northwind\nwind.bak'
209 WITH
210 MOVE 'northwind' TO 'd:\Program Files\Microsoft SQL
211 Server\Data\nwind_new.mdf'
212 MOVE 'northwind_log' TO 'd:\Program Files\Microsoft SQL
213 Server\Data\nwind_new_log.ldf'
214 SELECT *
215 FROM OPENDATASOURCE(
216 'Microsoft.Jet.OLEDB.4.0',
217 'Data Source=C:\test.xls;Extended Properties=EXCEL 5.0'
218 )...[Sheet1$];
219
220 SELECT * FROM
221 OpenDataSource(
222 'Microsoft.Jet.OLEDB.4.0',
223 'Data Source="c:\temp\payroll.mdb";
224 User ID=Admin;Password=;')...employees
225
226
227 SELECT *
228 FROM OPENROWSET
229 ( BULK 'C:\data.txt',SINGLE_CLOB)
230 AS a
【转】T-SQL 教程的更多相关文章
- 郝斌老师的SQL教程
时隔两年,重拾数据库编程.郝斌老师的sql教程通俗易懂,用作复习简直不能太赞.
- SQL 教程
SQL 教程 http://www.w3school.com.cn/sql/
- 请推荐一本SQL教程
sql系列教程如下 sql教程 SQL 是用于访问和处理数据库的标准的计算机语言. 在本教程中,您将学到如何使用 SQL 访问和处理数据系统中的数据, 这类数据库包括:mysql.SQL Server ...
- SQL 教程数据库包括:Oracle, Sybase, SQL Server, DB2, Access 等等,您将学到如何使用 SQL 访问和处理数据系统中的数据
SQL 基础教程 SQL 教程 SQL 简介 SQL 语法 SQL select SQL distinct SQL where SQL AND & OR SQL Order By SQL in ...
- 学习笔记之SQL 教程
SQL 教程 | 菜鸟教程 http://www.runoob.com/sql/sql-tutorial.html SQL,指结构化查询语言,全称是 Structured Query Language ...
- w3c上的SQL 教程---基本语法 语句学习
SQL 教程路径:http://www.w3school.com.cn/sql/index.asp
- SQL-W3School-基础:SQL 教程
ylbtech-SQL-W3School-基础:SQL 教程 1.返回顶部 1. SQL 是用于访问和处理数据库的标准的计算机语言. 在本教程中,您将学到如何使用 SQL 访问和处理数据系统中的数据, ...
- SQL 教程学习进度备忘
书签:跳过:另外跳过的内容有待跟进 __________________ 学习资源:W3School. _________________ 跳过的内容: 1. “SQL select”底部的“ AD ...
- [SQL] SQL学习笔记之基础操作
1 SQL介绍 SQL 是用于访问和处理数据库的标准的计算机语言.关于SQL的具体介绍,我们通过回答如下三个问题来进行. SQL 是什么? SQL,指结构化查询语言,全称是 Structured Qu ...
- W3Cschool菜鸟教程离线版下载链接
请在电脑上打开以下链接进行下载w3cschool 离线版(chm):http://pan.baidu.com/s/1bniwRCV(最新,2014年10月21日更新)w3cschool 离线版(htm ...
随机推荐
- yii2数据修改|联查
model 层 联查 $con = Yii::$app->db; $re = $con->createCommand("select * from ads LEFT JOIN ...
- ZOJ 1076 Gene Assembly
原题链接 题目大意:首先学习一个生物学的单词,exon:外显子,DNA序列中能够翻译表达的片段.给出很多外显子的起始点和终点,求寻找包含最多外显子的一条链,并且输出这些外显子的编号. 解法:先把所有外 ...
- JavaWeb学习记录(二十三)——文件上传与下载
一.导入jar包
- 按Right-BICEP的测试用例
测试方法:Right-BICEP 测试计划 1.Right-结果是否正确? 2.B-是否所有的边界条件都是正确的? 3.P-是否满足性能要求? 4.结果是否有符合要求的20道题目? 5.所得到的最大数 ...
- Oozie的安装过程
依赖CDH5,JDK和关系数据库 集群规划 主机名 IP Ooize节点 CHD1 XX.XX.XX.XX oozie server,oozie ...
- 《苹果开发之Cocoa编程》挑战2 创建一个数据源 练习
<苹果开发之Cocoa编程>第4版 P87 创建一个to-do list应用程序,在文本框中输入任务.当用户单击Add按钮时,添加字符串到一个变长队列,新任务就出现在list的末尾. 关键 ...
- Firefox-常用扩展
抓包: HttpFox,相比 Firebug 在页面跳转或刷新时依旧保持原有数据 常用User-Agent模拟: User Agent Switcher 更改请求头: ModifyHeaders 更改 ...
- MySQL 用户与授权管理详解
大纲 一.前言 二.创建用户并授权 三.GRANT语句的种类 四.撤权并删除用户 一.前言 做为Mysql数据库管理员管理用户账户,是一件很重要的事,指出哪个用户可以连接服务器,从哪里连接,连接后能做 ...
- memcache中的add和set方法区别
相信大家对memcache都不陌生,在项目中也经常使用memcache作为缓存方案,那么在使用过程中有没有发现为什么memcahce有两个添加缓存的方法:一个是add,一个是set,那么你知道这2个方 ...
- 关于C# 中的Attribute 特性
关于C# 中的Attribute 特性 作者: 钢钢 来源: 博客园 发布时间: 2011-01-09 23:30 阅读: 13921 次 推荐: 12 原文链接 [收藏] 摘要:纠结地说 ...