變量
局部變量
1.聲明局部變量
@where NVARCHAR(4000), @whereFORhruserinfo NVARCHAR(4000) = '', @order NVARCHAR(200) = '', @pagesize INT,--每頁有幾條數據 @page INT,--當前頁數 @totalRecorder INT OUTPUT
2.為變量賦值
SET @變量名 =值 --set用於普通的賦值 SELECT @變量名 = 值 --用於從表中查詢數據並賦值,,可以一次給多個變量賦值 SET @name=‘張三’ SET @id = 1 SELECT @name = sName FROM student WHERE sId=@id
3.輸出變量的值
SELECT 以表格的方式輸出,可以同時輸出多個變量;而PRINT 則是以文本的方式輸出,一次只能輸出一個變量的值。
SELECT @name,@id PRINT @name PRINT @id print @name,@id --錯誤!!
全局變量

用全局變量
select @@LANGUAGE as '當前使用語言' select @@SERVERNAME as '當前服務器名稱' select @@TRANCOUNT as '當前連接打開的事務數' select @@MAX_CONNECTIONS as '可以同時連接的最大數目' select @@VERSION as '當前服務器版本' select @@ERROR as '最后一個T-SQL錯誤的錯誤號'
IF ELSE
條件選擇語法
IF(條件表達式) BEGIN --相當於C#里的{ 語句1 …… END --相當於C#里的} ELSE BEGIN 語句1 …… END
WHILE
循環語句語法
WHILE(條件表達式) BEGIN --相當於C#里的{ 語句 …… continue --退出本次循環 BREAK --退出整個循環 END --相當於C#里的}
計算1-100之間所有奇數的和
declare @index int = 1 declare @sum int = 0 while(@index <= 100) begin if(@index%2!=0) begin set @sum=@sum+@index end set @index=@index+1 end
存儲過程
新建存儲過程
Create PROCEDURE [dbo].[p_test] @type int AS BEGIN declare @count int declare @result varchar(50) if(@type =1) begin select @count = (select count(*) from dbo.UserGrowthDetail) set @result='求第一個總數' print @result return @count end else if(@type =2) begin select @count = (select count(*) from dbo.UserGrowthValue) set @result='求第二個總數' print @result return @count end END
執行存儲過程
GO DECLARE @return_value int EXEC @return_value = [dbo].[p_test] @type = 1 SELECT 'Return Value' = @return_value GO
存儲過程通用分頁
Create PROCEDURE [dbo].[WF_Pager] @tblName varchar(255), -- 表名 @strGetFields varchar(1000), -- 返回字段列表要足夠大 @orderName varchar(255), -- 字段名用於排序 @OrderType bit = 0,--0 升序 1降序 @PageSize int = 10, -- 頁尺寸 @PageIndex int, -- 頁碼 @strWhere varchar(1000) = '' ,-- 查詢條件(注意:不要加where) @RecordCount int output --總數 AS BEGIN DECLARE @sql nvarchar(4000) declare @sortStr varchar(50)--排序方式 if @OrderType!=1 --升序 set @sortStr=' asc ' else --降序 set @sortStr=' desc ' if @strWhere !='' set @strWhere=' where '+@strWhere SELECT @sql =N' DECLARE @temp int; DECLARE @minRecord int; DECLARE @PageSize int; DECLARE @PageIndex int; SET @temp = 0 SET @minRecord = 0 SET @PageSize ='+ cast(@PageSize as varchar(10)) +' SET @PageIndex = '+ cast(@PageIndex as varchar(10)) +' SELECT @RecordCount = COUNT(0) FROM '+@tblName+ @strWhere +' -- 限制每頁記錄數,默認每頁10項記錄 -- IF(@PageSize < 1) SET @PageSize = 10 -- 限制頁號 BEGIN -- IF(@PageIndex < 1) SET @PageIndex = 1 DECLARE @MaxPageIndex INT -- 最大頁數。 SET @MaxPageIndex = @RecordCount / @PageSize --(完整數量的頁的數量) IF(@RecordCount % @PageSize > 0) BEGIN SET @MaxPageIndex = @MaxPageIndex + 1 END IF (@MaxPageIndex = 0) BEGIN SET @MaxPageIndex=1 END IF(@PageIndex > @MaxPageIndex) SET @PageIndex = @MaxPageIndex SET @minRecord = (@PageIndex - 1) * @PageSize; SET @temp = @PageIndex * @PageSize; SELECT * FROM ( SELECT ROW_NUMBER() OVER (ORDER BY '+@orderName+@sortStr+') AS Item,'+@strGetFields+' FROM '+@tblName+ @strWhere +' ) AS T WHERE T.Item >= @minRecord + 1 AND T.Item <= @temp ' --執行 EXEC SP_EXECUTESQL @sql, N'@RecordCount varchar(10) output',@RecordCount output SELECT @RecordCount END
存儲過程綜合示例
USE [SCST] GO /****** Object: StoredProcedure [dbo].[p_test] Script Date: 2018/8/23 19:43:19 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER PROCEDURE [dbo].[p_test] @strWhere varchar(1000), @PageSize int = 10, -- 頁尺寸 @PageIndex int = 0, -- 頁碼 @RecordCount int output --輸出參數 總數 AS BEGIN DECLARE @Result nvarchar(50) IF(@strWhere=1) BEGIN --CET公共表表達式 with tbStudent as ( select * from Student where Ssex = '男' ) SELECT @Result = (select count(*) from tbStudent) --輸出參數賦值 SELECT @RecordCount=1 END ELSE BEGIN SELECT dense_rank() OVER (ORDER BY s.Sage DESC) AS Rank,ROW_NUMBER() OVER(ORDER BY s.S# ASC) as RowNumber,s.S#,s.Sname,s.Ssex,ISNULL(s.Ssex,'空值') as Ssex, Sage=(case Sage when 17 then '小' when 18 then '正好' when 19 then '大' end ) from Student s SELECT CAST('12' AS int) SELECT CONVERT(VARCHAR(19),GETDATE()) --exists --while declare @index int = 1 declare @sum int = 0 while(@index <= 100) begin if(@index%2!=0) begin set @sum=@sum+@index end set @index=@index+1 end print @sum SET @Result = '2' SELECT @RecordCount=2 END print @Result return @Result END
USE [Points2019] GO /****** Object: StoredProcedure [dbo].[p_Page] Script Date: 2019/8/6 13:28:52 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE PROCEDURE [dbo].[p_Page] -- Add the parameters for the stored procedure here @SQL NVARCHAR(4000), @Order NVARCHAR(200), @CurPage INT, @PageRows INT, @TotalRecorder INT OUTPUT AS BEGIN -- SET NOCOUNT ON added to prevent extra result sets from SET NOCOUNT ON; DECLARE @ExceSQL NVARCHAR(4000) --獲得記錄數 SET @ExceSQL = 'select @TotalRecorder=count(*) from ' + substring(@SQL, charindex('YanFaFrom', @SQL) + 9, len(@SQL) - charindex('YanFaFrom', @SQL) - 8) EXECUTE sp_executesql @ExceSQL, N'@TotalRecorder int output', @TotalRecorder OUTPUT --設置開始行號 DECLARE @start_row_num AS INT SET @start_row_num = (@CurPage - 1) * @PageRows + 1 --設置標識語句 DECLARE @RowNumber NVARCHAR(300) IF (isnull(@Order, '') = '') BEGIN SET @Order = '(select 0)' END SET @RowNumber = ', ROW_NUMBER() OVER(ORDER BY ' + @Order + ') as RowNumber from ' SET @SQL = Replace(@SQL, 'YanFaFrom', @RowNumber) --設置查詢語句 SET @ExceSQL = 'WITH tmp AS (' + @SQL + ') select * from tmp where RowNumber between ' + Convert(NVARCHAR, @start_row_num) + ' And ' + Convert(NVARCHAR, @start_row_num + @PageRows - 1) + ' ORDER BY RowNumber asc' EXECUTE (@ExceSQL) PRINT @ExceSQL END GO
存儲過程和函數的區別
基本不同:
函數必須有一個返回值而存儲過程則不是必須的(存儲過程可以返回0個到n個值);
函數只能有輸入參數而存儲過程可以同時又輸入和輸出參數;
函數至少有一個參數而存儲過程可能需要n個參數;
函數可以被存儲過程調用而存儲過程不可以被函數調用;
高級不同:
存儲過程允許SELECT還有DML(INSERT/UPDATE/DELETE)語句而函數只能使用SELECT語句;
存儲過程不可以使用在WHERE/HAVING/SELECT語句中而函數可以;
返回表變量的函數可以和其他表進行JOIN操作;
內聯函數可以看做一個帶參數的VIEW去和其他表進行JOIN操作;
存儲過程可以使用try-catch塊進行異常處理二函數不可以;
存儲過程中可以使用事務而函數不可以;
總結:
函數有且只有一個輸入參數和一個返回值,而存儲過程沒有這個限制;
返回表變量的函數可以當做VIEW或者臨時表用在WHERE/HAVING/SELECT/JOIN語句中而存儲過程不可以;
存儲過程中可以使用try-catch塊和事務,而函數中不可以
實戰
1.可以將耗時的查詢先查出來放到臨時表中,給需要創建索引的字段創建索引。然后用該臨時表和主表做join查詢。
SET @s = 'select * into # from v_hruserinfo WHERE 1=1 ' + @whereFORhruserinfo+';'
select * into #Table from v_Table CREATE UNIQUE INDEX TMPUNIQUEHRU ON #Table(XXField) CREATE INDEX TMPHRU ON #Table (XXField)
2.使用公用表表達式可以使存儲過程更加優雅
WITH CTE AS ( )
資料
https://www.cnblogs.com/skybreak/p/3642593.html
