SQLServer - 存储过程基本语法

oracle的建表sql转成sqlserver的建表sql时的注意点 :

1.所有的comment语句需要删除。

2.clob类型转换为text类型。

3.blob类型转换为image类型。

4.number类型转换为int,number(16,2)等转换为decimal(16,2),number(18)转换为bigint。

5.default sysdate改为default getDate()。

6.to_date(‘2009-12-18‘,‘yyyy-mm-dd‘)改为cast(‘2009-12-18‘  as   datetime)

SQLSERVER:

变量的声明:

声明变量时必须在变量前加@符号

DECLARE @I INT

变量的赋值:

变量赋值时变量前必须加set

SET @I = 30

声明多个变量:

DECLARE @s varchar(10),@a INT

if语句:

if ..
begin
  ...
end
else if ..
begin
  ...
end
else
begin
  ...
end

Example:

DECLARE @d INT
set @d = 1
IF @d = 1 BEGIN
   PRINT ‘正确‘
END
ELSE BEGIN
   PRINT ‘错误‘
END

多条件选择语句:

Example:

declare @today int
declare @week nvarchar(3)
set @today=3
set @week= case
     when @today=1 then ‘星期一‘
     when @today=2 then ‘星期二‘
     when @today=3 then ‘星期三‘
     when @today=4 then ‘星期四‘
     when @today=5 then ‘星期五‘
     when @today=6 then ‘星期六‘
     when @today=7 then ‘星期日‘
     else ‘值错误‘
end
print @week

循环语句:

WHILE 条件 BEGIN
执行语句
END

Example:

DECLARE @i INT
SET @i = 1
WHILE @i<1000000 BEGIN
set @[email protected]+1
END

定义游标:

DECLARE @cur1 CURSOR FOR SELECT .........

OPEN @cur1
FETCH NEXT FROM @cur1 INTO 变量
WHILE(@@FETCH_STATUS=0)
BEGIN
处理.....
FETCH NEXT FROM @cur1 INTO 变量
END
CLOSE @cur1
DEALLOCATE @cur1
AS

declare @CATEGORY_CI_TABLENAME VARCHAR(50) =‘‘
declare @result VARCHAR(2000) = ‘‘
declare @CI_ID DECIMAL = 0
declare @num int = 1
declare @countnum int = 1

BEGIN
select  @countnum = count(ATTRIBUTE_CONFIG_ID) from T_ATTRIBUTE_CONFIG where CMDB_UPDATE_FLAG= ‘Y‘ and CATEGORY_CODE [email protected]_CODE

IF (@ATTRIBUTE2=‘A‘)
  begin
		DECLARE MyCursor CURSOR for select ATTRIBUTE_CONFIG_CODE from T_ATTRIBUTE_CONFIG where  CMDB_UPDATE_FLAG= ‘Y‘ and CATEGORY_CODE [email protected]_CODE
		 OPEN MyCursor FETCH NEXT FROM MyCursor INTO @CONFIG_CODE
				set @result = @[email protected]_CODE+‘,‘
			 WHILE @@FETCH_STATUS = 0
					BEGIN
					FETCH NEXT FROM MyCursor INTO @CONFIG_CODE
					set @num = @num+ 1
						if(@num<@countnum)
							begin
								set @result = @[email protected]_CODE+‘,‘
							end
						else if(@[email protected])
							 begin
								set @result = @result [email protected]_CODE
							 end
					END
			CLOSE MyCursor
			DEALLOCATE MyCursor
	    set @result = ‘insert into ‘ + @ATTRIBUTE1 + ‘(‘ + @result +‘) select ‘+ @result +‘ from ‘[email protected]_CI_TABLENAME +‘ where CI_ORDER_LINE_ID=‘[email protected]_ID
  end
 else if((@ATTRIBUTE2=‘U‘))

临时表:

-- Select INTO 从一个查询的计算结果中创建一个新表。 数据并不返回给客户端,这一点和普通的Select 不同。 新表的字段具有和 Select 的输出字段相关联(相同)的名字和数据类型。

select * into NewTable

from Uname

-- Insert INTO ABC Select

-- 表ABC必须存在

-- 把表Uname里面的字段Username复制到表ABC

Insert INTO ABC Select Username FROM Uname

-- 创建临时表

Create TABLE #temp(

UID int identity(1, 1) PRIMARY KEY,

UserName varchar(16),

Pwd varchar(50),

Age smallint,

Sex varchar(6)

)

-- 打开临时表

Select * from #temp

1、局部临时表(#开头)只对当前连接有效,当前连接断开时自动删除。

2、全局临时表(##开头)对其它连接也有效,在当前连接和其他访问过它的连接都断开时自动删除。

3、不管局部临时表还是全局临时表,只要连接有访问权限,都可以用drop table #Tmp(或者drop table ##Tmp)来显式删除临时表。

临时表对执行效率应该影响不大,只要不是太过份,相反可以提高效率特别是连接查询的地方,只要你的数据库临时表空间足够

游标多,会严重执行效率,能免则免!

临时表在不同数据库设计中的作用

SQLSERVER 存储过程 语法

===============================================================================

其他:

--有输入参数的存储过程--

create proc GetComment

(@commentid int)

as

select * from Comment where [email protected]

--有输入与输出参数的存储过程--

create proc GetCommentCount

@newsid int,

@count int output

as

select @count=count(*) from Comment where [email protected]

--返回单个值的函数--

create function MyFunction

(@newsid int)

returns int

as

begin

declare @count int

select @count=count(*) from Comment where [email protected]

return @count

end

--调用方法--

declare @count int

exec @count=MyFunction 2

print @count

--返回值为表的函数--

Create function GetFunctionTable

(@newsid int)

returns table

as

return

(select * from Comment where [email protected])

--返回值为表的函数的调用--

select * from GetFunctionTable(2)

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

SQLServer 存储过程中不拼接SQL字符串实现多条件查询

 以前拼接的写法

  set @sql=‘ select * from table where 1=1 ‘

  if (@addDate is not null)

   set @sql = @sql+‘ and addDate = ‘+ @addDate + ‘ ‘

  if (@name <>‘‘ and is not null)

   set @sql = @sql+ ‘ and name = ‘ + @name + ‘ ‘

  exec(@sql)

下面是 不采用拼接SQL字符串实现多条件查询的解决方案

  第一种写法是 感觉代码有些冗余

  if (@addDate is not null) and (@name <> ‘‘)

   select * from table where addDate = @addDate and name = @name

  else if (@addDate is not null) and (@name =‘‘)

   select * from table where addDate = @addDate

  else if(@addDate is null) and (@name <> ‘‘)

   select * from table where and name = @name

  else if(@addDate is null) and (@name = ‘‘)

  select * from table

  第二种写法是

  select * from table where (addDate = @addDate or @addDate is null) and (name = @name or @name = ‘‘)

  第三种写法是

  SELECT * FROM table where

  addDate = CASE @addDate IS NULL THEN addDate ELSE @addDate END,

  name = CASE @name WHEN ‘‘ THEN name ELSE @name END

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

SQLSERVER存储过程基本语法

一、定义变量

--简单赋值
[email protected]
[email protected]=5
print @a
  
--使用select语句赋值
[email protected] nvarchar(50)
[email protected]=‘张三‘
print @user1
[email protected] nvarchar(50)
sele[email protected] =NamefromST_UserwhereID=1
print @user2
  
--使用update语句赋值
[email protected] nvarchar(50)
[email protected] =NamewhereID=1
print @user3

 

二、表、临时表、表变量

--创建临时表1
createtable#DU_User1
(
     [ID] [int] NOTNULL,
     [Oid] [int]NOTNULL,
     [Login] [nvarchar](50)NOTNULL,
     [Rtx] [nvarchar](4)NOTNULL,
     [Name] [nvarchar](5)NOTNULL,
     [Password] [nvarchar](max)NULL,
     [State] [nvarchar](8)NOTNULL
);
--向临时表1插入一条记录
insertinto#DU_User1 (ID,Oid,[Login],Rtx,Name,[Password],State)values(100,2,‘LS‘,‘0000‘,‘临时‘,‘321‘,‘特殊‘);
  
--从ST_User查询数据,填充至新生成的临时表
select*into#DU_User2fromST_UserwhereID<8
  
--查询并联合两临时表
select*from#DU_User2whereID<3unionselect*from#DU_User1
  
--删除两临时表
droptable#DU_User1
droptable#DU_User2
--创建临时表
CREATETABLE#t
(
    [ID] [int]NOTNULL,
    [Oid] [int]NOTNULL,
    [Login] [nvarchar](50)NOTNULL,
    [Rtx] [nvarchar](4)NOTNULL,
    [Name] [nvarchar](5)NOTNULL,
    [Password] [nvarchar](max)NULL,
    [State] [nvarchar](8)NOTNULL,
)
  
--将查询结果集(多条数据)插入临时表
insertinto#tselect*fromST_User
--不能这样插入
--select * into #t from dbo.ST_User
  
--添加一列,为int型自增长子段
altertable#tadd[myid]intNOTNULLIDENTITY(1,1)
--添加一列,默认填充全球唯一标识
altertable#tadd[myid1] uniqueidentifierNOTNULLdefault(newid())
  
select*from#t
droptable#t
--给查询结果集增加自增长列
  
--无主键时:
selectIDENTITY(int,1,1)asID,Name,[Login],[Password]into#tfromST_User
select*from#t
  
--有主键时:
select(selectSUM(1)fromST_UserwhereID<= a.ID)asmyID,*fromST_User aorderbymyID
--定义表变量
[email protected]
(
    idintnotnull,
    msg nvarchar(50)null
)
[email protected](1,‘1‘)
[email protected](2,‘2‘)
select*[email protected]

 三、循环

--while循环计算1到100的和
[email protected]
[email protected]
[email protected]=1
[email protected]=0
while @a<=100
begin
    [email protected][email protected]
    [email protected]+=1
end
print @sum

四、条件语句

--if,else条件分支
if(1+1=2)
begin
    print‘对‘
end
else
begin
    print‘错‘
end
  
--when then条件分支
[email protected]
[email protected] nvarchar(3)
[email protected]=3
[email protected]=case
    [email protected]=1then‘星期一‘
    [email protected]=2then‘星期二‘
    [email protected]=3then‘星期三‘
    [email protected]=4then‘星期四‘
    [email protected]=5then‘星期五‘
    [email protected]=6then‘星期六‘
    [email protected]=7then‘星期日‘
    else‘值错误‘
end
print @week

 

五、游标

[email protected]
[email protected]
[email protected](50)
  
--定义一个游标
declareuser_curcursorforselectID,Oid,[Login]fromST_User
--打开游标
openuser_cur
while @@fetch_status=0
begin
--读取游标
    [email protected],@Oid,@Login
    print @ID
    --print @Login
end
closeuser_cur
--摧毁游标
deallocateuser_cur

六、触发器

   触发器中的临时表:

  Inserted

  存放进行insert和update 操作后的数据

  Deleted

  存放进行delete 和update操作前的数据

--创建触发器
CreatetriggerUser_OnUpdate 
    OnST_User 
    forUpdate 
As 
    [email protected] nvarchar(50)
    [email protected]记录修改情况
    [email protected] = N‘姓名从“‘+ Deleted.Name+ N‘”修改为“‘+ Inserted.Name+‘”‘fromInserted,Deleted
    --插入日志表
    insertinto[LOG](MSG)values(@msg)
      
--删除触发器
droptriggerUser_OnUpdate

七、存储过程

--创建带output参数的存储过程
CREATEPROCEDUREPR_Sum
    @aint,
    @bint,
    @sumintoutput
AS
BEGIN
    [email protected][email protected][email protected]
END
  
--创建Return返回值存储过程
CREATEPROCEDUREPR_Sum2
    @aint,
    @bint
AS
BEGIN
    [email protected][email protected]
END
      
--执行存储过程获取output型返回值
[email protected]
executePR_Sum 1,2,@mysumoutput
print @mysum
  
--执行存储过程获取Return型返回值
[email protected]
[email protected]= PR_Sum2 1,2
print @mysum2

八、自定义函数

  函数的分类:

    1)标量值函数

    2)表值函数

        a:内联表值函数

        b:多语句表值函数

    3)系统函数

--新建标量值函数
createfunctionFUNC_Sum1
(
    @aint,
    @bint
)
returnsint
as
begin
    [email protected][email protected]
end
  
--新建内联表值函数
createfunctionFUNC_UserTab_1
(
    @myIdint
)
returnstable
as
return(select*fromST_UserwhereID<@myId)
  
--新建多语句表值函数
createfunctionFUNC_UserTab_2
(
    @myIdint
)
[email protected]
(
    [ID] [int]NOTNULL,
    [Oid] [int]NOTNULL,
    [Login] [nvarchar](50)NOTNULL,
    [Rtx] [nvarchar](4)NOTNULL,
    [Name] [nvarchar](5)NOTNULL,
    [Password] [nvarchar](max)NULL,
    [State] [nvarchar](8)NOTNULL
)
as
begin
    [email protected]*fromST_UserwhereID<@myId
    return
end
  
--调用表值函数
select*fromdbo.FUNC_UserTab_1(15)
--调用标量值函数
[email protected]
[email protected]=dbo.FUNC_Sum1(100,50)
print @s
  
--删除标量值函数
dropfunctionFUNC_Sum1

谈谈自定义函数与存储过程的区别:

一、自定义函数:

  1. 可以返回表变量

  2. 限制颇多,包括

    不能使用output参数;

    不能用临时表;

    函数内部的操作不能影响到外部环境;

    不能通过select返回结果集;

    不能update,delete,数据库表;

  3. 必须return 一个标量值或表变量

  自定义函数一般用在复用度高,功能简单单一,争对性强的地方。

二、存储过程

  1. 不能返回表变量

  2. 限制少,可以执行对数据库表的操作,可以返回数据集

  3. 可以return一个标量值,也可以省略return

   存储过程一般用在实现复杂的功能,数据操纵方面。

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

SqlServer存储过程--实例

实例1:只返回单一记录集的存储过程。

  表银行存款表(bankMoney)的内容如下


Id


userID


Sex


Money


001


Zhangsan



30


002


Wangwu



50


003


Zhangsan



40

要求1:查询表bankMoney的内容的存储过程

create procedure sp_query_bankMoney

as

select * from bankMoney

go

exec sp_query_bankMoney

注*  在使用过程中只需要把T-Sql中的SQL语句替换为存储过程名,就可以了很方便吧!

实例2(向存储过程中传递参数):

加入一笔记录到表bankMoney,并查询此表中userID= Zhangsan的所有存款的总金额。

Create proc insert_bank @param1 char(10),@param2 varchar(20),@param3 varchar(20),@param4 int,@param5 int output

with encryption ---------加密

as

insert into bankMoney (id,userID,sex,Money)

Values(@param1,@param2,@param3, @param4)

select @param5=sum(Money) from bankMoney where userID=‘Zhangsan‘

go

在SQL Server查询分析器中执行该存储过程的方法是:

declare @total_price int

exec insert_bank ‘004‘,‘Zhangsan‘,‘男‘,100,@total_price output

print ‘总余额为‘+convert(varchar,@total_price)

go

在这里再啰嗦一下存储过程的3种传回值(方便正在看这个例子的朋友不用再去查看语法内容):

1.以Return传回整数

2.以output格式传回参数

3.Recordset

传回值的区别:

output和return都可在批次程式中用变量接收,而recordset则传回到执行批次的客户端中。

实例3:使用带有复杂 SELECT 语句的简单过程

  下面的存储过程从四个表的联接中返回所有作者(提供了姓名)、出版的书籍以及出版社。该存储过程不使用任何参数。

  USE pubs

IF EXISTS (SELECT name FROM sysobjects

WHERE name = ‘au_info_all‘ AND type = ‘P‘)

DROP PROCEDURE au_info_all

GO

CREATE PROCEDURE au_info_all

AS

SELECT au_lname, au_fname, title, pub_name

FROM authors a INNER JOIN titleauthor ta

ON a.au_id = ta.au_id INNER JOIN titles t

ON t.title_id = ta.title_id INNER JOIN publishers p

ON t.pub_id = p.pub_id

GO

  au_info_all 存储过程可以通过以下方法执行:

  EXECUTE au_info_all

-- Or

EXEC au_info_all

  如果该过程是批处理中的第一条语句,则可使用:

  au_info_all

实例4:使用带有参数的简单过程

  CREATE PROCEDURE au_info

@lastname varchar(40),

@firstname varchar(20)

AS

SELECT au_lname, au_fname, title, pub_name

FROM authors a INNER JOIN titleauthor ta

ON a.au_id = ta.au_id INNER JOIN titles t

ON t.title_id = ta.title_id INNER JOIN publishers p

ON t.pub_id = p.pub_id

WHERE  au_fname = @firstname

AND au_lname = @lastname

GO

  au_info 存储过程可以通过以下方法执行:

  EXECUTE au_info ‘Dull‘, ‘Ann‘

-- Or

EXECUTE au_info @lastname = ‘Dull‘, @firstname = ‘Ann‘

-- Or

EXECUTE au_info @firstname = ‘Ann‘, @lastname = ‘Dull‘

-- Or

EXEC au_info ‘Dull‘, ‘Ann‘

-- Or

EXEC au_info @lastname = ‘Dull‘, @firstname = ‘Ann‘

-- Or

EXEC au_info @firstname = ‘Ann‘, @lastname = ‘Dull‘

  如果该过程是批处理中的第一条语句,则可使用:

  au_info ‘Dull‘, ‘Ann‘

-- Or

au_info @lastname = ‘Dull‘, @firstname = ‘Ann‘

-- Or

au_info @firstname = ‘Ann‘, @lastname = ‘Dull‘


实例5:使用带有通配符参数的简单过程

CREATE PROCEDURE au_info2

@lastname varchar(30) = ‘D%‘,

@firstname varchar(18) = ‘%‘

AS

SELECT au_lname, au_fname, title, pub_name

FROM authors a INNER JOIN titleauthor ta

ON a.au_id = ta.au_id INNER JOIN titles t

ON t.title_id = ta.title_id INNER JOIN publishers p

ON t.pub_id = p.pub_id

WHERE au_fname LIKE @firstname

AND au_lname LIKE @lastname

GO

  au_info2 存储过程可以用多种组合执行。下面只列出了部分组合:

  EXECUTE au_info2

-- Or

EXECUTE au_info2 ‘Wh%‘

-- Or

EXECUTE au_info2 @firstname = ‘A%‘

-- Or

EXECUTE au_info2 ‘[CK]ars[OE]n‘

-- Or

EXECUTE au_info2 ‘Hunter‘, ‘Sheryl‘

-- Or

EXECUTE au_info2 ‘H%‘, ‘S%‘

  = ‘proc2‘

实例6:if...else

存储过程,其中@case作为执行update的选择依据,用if...else实现执行时根据传入的参数执行不同的修改.

--下面是if……else的存储过程:

if exists (select 1 from sysobjects where name = ‘Student‘ and type =‘u‘ )

drop table Student

go

if exists (select 1 from sysobjects where name = ‘spUpdateStudent‘ and type =‘p‘ )

drop proc spUpdateStudent

go

create table Student

(

fName nvarchar (10),

fAge

smallint ,

fDiqu varchar (50),

fTel  int

)

go

insert into Student values (‘X.X.Y‘ , 28, ‘Tesing‘ , 888888)

go

create proc spUpdateStudent

(

@fCase int ,

@fName nvarchar (10),

@fAge smallint ,

@fDiqu varchar (50),

@fTel  int

)

as

update Student

set fAge = @fAge, -- 传 1,2,3 都要更新 fAge 不需要用 case

fDiqu = (case when @fCase = 2 or @fCase = 3 then @fDiqu else fDiqu end ),

fTel  = (case when @fCase = 3 then @fTel else fTel end )

where fName = @fName

select * from Student

go

-- 只改 Age

exec spUpdateStudent

@fCase = 1,

@fName = N‘X.X.Y‘ ,

@fAge = 80,

@fDiqu = N‘Update‘ ,

@fTel  = 1010101

-- 改 Age 和 Diqu

exec spUpdateStudent

@fCase = 2,

@fName = N‘X.X.Y‘ ,

@fAge = 80,

@fDiqu = N‘Update‘ ,

@fTel  = 1010101

-- 全改

exec spUpdateStudent

@fCase = 3,

@fName = N‘X.X.Y‘ ,

@fAge = 80,

@fDiqu = N‘Update‘ ,

@fTel  = 1010101

时间: 2024-08-06 03:40:35

SQLServer - 存储过程基本语法的相关文章

SQLServer存储过程基本语法

SQLSERVER: 变量的声明:声明变量时必须在变量前加@符号DECLARE @I INT 变量的赋值:变量赋值时变量前必须加setSET @I = 30 声明多个变量:DECLARE @s varchar(10),@a INT if语句: Java代码 if .. begin ... end else if .. begin ... end else begin ... end Example: Sql代码 DECLARE @d INT set @d = 1 IF @d = 1 BEGIN

SQLSERVER存储过程基本语法使用

一.定义变量 --简单赋值 declare @a int set @a=5 print @a --使用select语句赋值 declare @user1 nvarchar(50) select @user1='张三' print @user1 declare @user2 nvarchar(50) select @user2 = Name from ST_User where ID=1 print @user2 --使用update语句赋值 declare @user3 nvarchar(50)

SQLSERVER存储过程语法具体解释

SQL SERVER存储过程语法: Create PROC [ EDURE ] procedure_name [ ; number ]     [ { @parameter data_type }         [ VARYING ] [ = default ] [ OUTPUT ]     ] [ ,...n ] [ WITH     { RECOMPILE | ENCRYPTION | RECOMPILE , ENCRYPTION } ] [ FOR REPLICATION ] AS sq

SQLSERVER存储过程语法详解

SQL SERVER存储过程语法: Create PROC [ EDURE ] procedure_name [ ; number ]     [ { @parameter data_type }         [ VARYING ] [ = default ] [ OUTPUT ]     ] [ ,...n ] [ WITH     { RECOMPILE | ENCRYPTION | RECOMPILE , ENCRYPTION } ] [ FOR REPLICATION ] AS sq

SqlServer和mysql几个不同之处(主要是存储过程的语法)

1.SqlServer中的类型bit(1)对应MySQL的tinyint(1) 2.SqlServer中用getdate()获取数据库系统当前时间;MySQL中NOW()获取数据库系统当前时间 3.SqlServer中转型需要用cast,mysql不需要用cast; 4.SqlServer存储过程中循环中退出需要用break,mysql用leave

SqlServer存储过程(增删改查)

* IDENT_CURRENT 返回为任何会话和任何作用域中的特定表最后生成的标识值. CREATE PROCEDURE [dbo].[PR_NewsAffiche_AddNewsEntity] ( @NewsTitle varchar(200), @NewsContent varchar(4000), @Creator varchar(50), @LastNewsId int output, @DepartId int ) AS BEGIN SET NOCOUNT ON; insert int

创建并在项目中调用SQLSERVER存储过程的简单示例

使用SQLSERVER存储过程可以很大的提高程序运行速度,简化编程维护难度,现已得到广泛应用.创建存储过程 和数据表一样,在使用之前需要创建存储过程,它的简明语法是: 引用: Create PROC 存储过程名称 [参数列表(多个以","分隔)] AS SQL 语句 例: 引用: Create PROC upGetUserName @intUserId INT, @ostrUserName NVARCHAR(20) OUTPUT -- 要输出的参数 AS BEGIN -- 将uName

对sqlserver存储过程合游标的一些理解

在最近老板给我的数据库操作要求中,有一张类似购物清单样式的表,表中有客户ID,商品ID,商品数量,单价和商品总价,出售日期.还有一张商品折扣信息表,在这基础上商品价格同一商品价格会有差异,不同客户最高折扣额不同,折扣率也有差异,要求用sqlserver存储过程合游标表诉 一开始根本没有思路和头绪,听老大讲解是要用存储过程将查询到的数据存储好,再用游标循环遍历.对于存储过程合游标的表诉一直不太熟,之前只是将用sql语句查到的结果集放到存储过程里面,对于游标的了解不够深入.所以一开始也是想着用sql

SqlServer存储过程传入Table参数

今天是周日,刚好有空闲时间整理一下这些天工作业务中遇到的问题. 有时候我们有这样一个需求,就是在后台中传过来一个IList<类>的泛型集合数据,该集合是某个类的实例集合体,然后将该集合中的实例的数据一个个地插入到数据库或者更新到数据库中去.一开始我想到的方法是拼接字符串,然后通过存储过程对接收到的字符串进行截取,再一个个地插入或者更新到数据库中去,这是最原始的方法,不过过程会比较复杂,想到这就头疼.后来查找发现说SqlServer2008中为存储过程添加了一个新特性,可以传递表类型的参数,既然