学习交流,欢迎转载。转载请注明文章来源:http://www.cnblogs.com/lgjspace/archive/2011/10/13/2218273.html
细节:
自定义函数和存储过程的用法没有什么区别,它有下面几种类型:
1. 内嵌表值函数(Inline Table-valued Function):只能返回一个表,而且不能对该表进行任何的逻辑操作(如 IF、WHILE 等),和存储过程不同,存储过程既可以返回一个或多个表,又可以返回单个值。
2. 多语句表值函数(Multi-statement Table-valued Function):和内嵌表值函数类似,也是只能返回一个表,但可以对表进行一些逻辑操作。
3. 标量函数(Scalar-valued Function):类似于只返回单个 int 类型值的存储过程,标量函数也只能返回单个值,但函数对返回值的类型没有限制,可以为任何类型,其它的没什么不同。
细节:
内嵌表值函数:
1. 在使用内嵌表值函数时,无论内嵌表值函数有没有设定参数,使用内嵌表值函数时参数列表的括号(即紧跟函数名后的一对圆括号)都必须得加上,否则报错。
2. 在内嵌表值函数中定义传入函数的参数时不需要加 declare 关键字,也不需要像定义一个表变量那样要写明 null、not null、Primary Key 等,只需要写明参数名和参数类型即可,如“@Birthday datetime”、“@Gender bit”等。
3. 在内嵌表值函数中,紧跟参数列表括号的是一个固定的语法“RETURNS TABLE”(注:是 RETURNS 而不是 RETURN),再紧跟后面就是关键字“AS”,再后面是“RETURN”(注:这里和前面相反,是 RETURN 而不是 RETURNS),再后面就是一个圆括号,括号中的就是该函数将要返回的表。
4. 内嵌表值函数可以当成一个普通的表来使用,使用上和普通的表没什么区别。
多语句表值函数:
1.在为多语句表值函数声明返回的表的结构时,不用写明 null、not null、Primary Key 等,只需要写上列名和列的数据类型即可。
经验:
1. 自定义函数的命名一般以“udf_”开头。
2. 一般用得比较多的情况都是在存储过程中调用某些标量函数。
3. 无论进行什么样的数据库开发,都要首先了解表结构,如果表结构不先于开发时了解,则开发就无从下手。
细节:
1. 在用 SQL 语句调用已经写好的内嵌表值函数时,被调用的内嵌表值函数就相当于一个表变量,在 SQL 中可以当作一个表来使用,使用时和使用一般的永久表没有什么区别。
2. 在使用内嵌表值函数时,实质上内嵌表值函数没有创建任何的表,只是相当于函数调用者的一个代理,为调用者执行函数体里面的 SQL 语句来查询真正的数据库。
区别:
自定义函数和存储过程的区别:
1. 自定义函数“相当于一个数据操作的代理”,只能对数据进行操作,函数本身不能存储数据;而存储过程除了可以操作数据之外,还能存储数据。
2. 自定义函数中对数据库的操作只能是“查”(Select),不能是任何的“增”、“删”、“改”,否则报错;而存储过程则可以。
细节:
1. SQL 中,自定义函数里声明变量要用关键字 Declare 来标记,就像 VB 中使用 Dim 关键字来声明变量一样。
区别:
“内嵌表值函数”和“多语句表值函数”的区别:
内嵌表值函数只能直接返回用 SQL 语句查询出来的表,AS RETURN() 部分的圆括号中只能有一个语句(Select 或 With 语句等),不能多于一句,不能对查出来的表进行二次筛选和逻辑处理;而多语句表值函数能对用 SQL 语句查询出来的表进行二次筛选和逻辑处理。
技巧:
在自定义函数或存储过程中,可以用下面的方法来为变量赋值(赋值的数据从一个表中得出):
--定义变量:
Declare @FirstName varchar(100),
@LastName varchar(100),
@JobTitle varchar(500)
--通过从表中查出的数据对变量赋值:
Select @FirstName = c.FirstName,
@LastName = c.LastName,
@JobTitle = e.Title
From Person.Contact as c
Join HumanResources.Employee as e
on e.ContactID = @ContactID
Where c.ContactID = '1001'
细节:
多语句表值函数格式:
CREATE FUNCTION [dbo].[udf_GetContactInformation] //Alter 是修改表,Create 是创建表。
(
@ContactID int //定义函数参数
)
RETURNS
@ContactInfo TABLE //定义要返回的表的表名(这里的表名为:@ContactInfo)
(
ContactID int
)
AS
BEGIN
//写要对表进行处理的逻辑代码
RETURN //这里的“RETURN”代表返回上面 CREATE 出来的表。
END
GO
细节:
在 SQL Server 中,变量都要加上 @ 作为前缀,无论是一般的变量还是表变量,都不例外。
细节:
1. SQL 中的标量函数是指:只返回一个值的函数,这点和只返回一个值的存储过程类似,但是只返回一个值的存储过程限定返回的值必须为整形,而标量函数则可以是几乎任意类型。
2. 标量函数里,返回值的类型是在填写函数参数的圆括号(即紧跟函数名的圆括号)后的关键字 RETURNS 定义的,把想要返回的数据类型关键字写在 RETURNS 后面即可设定函数的返回值类型。
区别:
SQL 自定义函数与存储过程的区别:
1. 自定义函数可以写在查询语句的Select/where/having后面,而存储过程不行。
2. 不能在函数中为(数据库中的永久)表插入、更新、删除数据,只能查询数据。
用法:
SQL 中的 decimal 类型的声明方法:
声明语法格式为:
Decimal(Length,Point)
其中:
Length 为 decimal 值的(包括整数部分和小数部分在内的)总长度;
Point 为保留的小数位数。
用法:
1. PRINT(content):把要传进来的 content 参数(参数为要打印的内容)打印到输出,该函数不同于 Select 语句打印出来的结果,PRINT() 打印出来的结果没有表格。
2. SPACE(number):根据 number 参数来创建指定个数的空格字符,空格字符的个数由参数 number 指定。
3. REPLACE(content, oldstr, newstr):把字符串 content 中含有的所有 oldstr 字符串都替换成字符串 newstr。
4. CONVERT(dataType, data):把数据 data 转换成指定的 dataType 类型的数据,并返回转换后的数据。
5. CAST(data as dataType):把数据 data 转换成指定的 dataType 类型的数据,并返回转换后的数据。
-- SQL 常用函数的使用语法例子:
--打印用双括号括起来的三个空格。
print('"' + SPACE(3) + '"')
--把字符串 “b b” 中的所有空格 “ ” 都替换成字符 “A”,然后打印出来。
print(Replace('b'+SPACE(5)+'b',' ','A'))
--两个类型转换函数 CONVERT() 和 CAST() 的使用语法。
Select CONVERT(int,'234'), CAST('234' as int)
用法:
identity(1,1) 是用来把列字段标记为自动增长字段,但该字段必须为 not null,且类型必须为整形 int。
注意:
SQL 语句中用“+”号连接多种类型时的默认类型转换:
如果一个 int 类型的和字符串类型的用“+”连接,则系统默认被转换为 int 类型。
细节:
游标使用起来很灵活,但十分消耗性能,慎重使用。
细节:
定义游标变量和定义其它变量有点不一样,游标变量的变量名不能用“@”开头。
具体使用步骤如下:
定义游标:
Declare CursorName Cursor For
SELECT C1,C2 FROM TableName
打开游标:
Open CursorName
让游标向指定的表中取值,并赋值给相应的自定义变量:
Fetch Next From CursorName
Into @C1,@C2
循环让游标往指定的表中取值,直到取不出值为止(该循环不是必须步骤,看业务需要):
While @@FETCH_STATUS = 0
Begin
——处理自定义的逻辑业务。
Fetch Next From CursorName into @C1, @C2
End
关闭游标:
CLOSE CursorName
释放游标:
DEALLOCATE CursorName
介绍:
SQL Server 中的触发器类似于 C# 里面的事件,它是在数据库的表发生某些操作(如 Insert、Delete、Update)时,触发某些预先定义好的业务逻辑操作。
触发器的语法如下:
--创建一个名为 TriggerName 的触发器
CREATE TRIGGER TriggerName
--设定触发器要监视的目标表,TargetTableName 为目标表的表明。
ON TargetTableName
--设置程序该何时触发触发器,这里表示在发生 UPDATE 操作时触发。
FOR UPDATE
AS
BEGIN
--在此进行自定义的业务逻辑操作。
END
GO
经验:
SQL 的触发器的一个典型应用场景:同步备份
假设有两台服务器,一台是正常的数据库服务器(暂名为 Server A),另一台是备份用的数据库服务器(暂名为 Server B),如果 Server A 的数据被更改了,可以通过设定触发器,让触发器为 Server B 中的相应数据进行和 Server A 同样的更改操作,以实现同步备份功能。
细节:
--为一个已有的表 t1 插入一个列 c1:
ALTER TABLE t1 ADD c1 int null
--从一个已有的表 t1 中删除名为 c1 的列:
ALTER TABLE t1 DROP COLUMN c1
经验教训:
用 SQL 删除触发器时不能仅仅用触发器的名称,还要指明触发器所在的数据表的表名称,否则会报这样的错:“无法对 触发器 'TriggerName' 执行 删除,因为它不存在,或者您没有所需的权限。”。
如下面的例子所示:
--创建一个触发器 TriggerName:
Create Trigger TriggerName
On Production.Product
For UPdate
AS
BEGIN
--进行自定义的逻辑操作,这里是更新表 Production.Product 的 myColumn 列。
Update Production.Product
Set myColumn = 1
END
GO
--删除触发器 TriggerName,这里只标明触发器的名称,没有指明触发器所在的数据表的表名称,执行该语句时报错:“无法对 触发器 'TriggerName' 执行 删除,因为它不存在,或者您没有所需的权限。”
Drop Trigger TriggerName
--也是删除触发器,但这里指明了触发器的名称和它所在的表的表名,因此能成功执行该语句。
Drop Trigger [Production].[TriggerName]
注意:
在 Visual Studio 中新建一个水晶报表时要注意,在“添加新项”对话框中,是选择“Crystal 报表”(后缀为.rpt),而不是“报表”(后缀为.rdlc),前者是水晶报表,后者是 SQL Server 的报表。