Sqlserver存儲過程—----傳遞數組、使用循環(huán) ? Sqlserver 存儲過程 數組 循環(huán) 背景: 前一段時間做過一個公司內部的員工項目管理系統(tǒng),其間有個sqlserver存儲過程是要從excel文件中讀取員工的項目信息我纪,并從db中找出相關的的其他信息插入到一張員工表中。這里涉及兩個難點:怎么向存儲過程傳遞多條記錄丐吓?在存儲過程中怎么對這些記錄一條條循環(huán)處理宣羊。
解決方案: 1. ? ? ?怎么將excel中數據傳入到存儲過程中? 存儲過程是沒有辦法接受數組參數的汰蜘,我的做法是先把excel中的信息導入到一張全局的臨時表中,在把臨時表的表名傳遞給存儲過程之宿,在存儲過程中使用臨時表內容族操。
2. ? ? ?怎么在存儲過程中做循環(huán)處理? 在存儲過程中新建一張臨時表比被,將傳遞過來的全局臨時表的信息保存在該表中色难,并且在表中添加一個id列,對記錄從一開始計數等缀。使用count函數計算記錄的個數枷莉,使用while語句對id從1到count進行循環(huán)
代碼:
1.創(chuàng)建臨時表:
IF OBJECT_ID('dbo.create_tempTable') IS NOT NULL ? ? DROP PROC dbo.create_tempTable; GO CREATE PROC dbo.create_tempTable ? ? AS ? ? ? CREATE TABLE ##tempexcel( ? ? ? ? pjid char(6),--項目id ? ? ? ? userid char(6),--用戶id ? ? ? ? PRIMARY KEY(pjid, userid) ? ? ) ? ?GO
2.具體操作的存儲過程:
IF OBJECT_ID('dbo.Staff_insert') IS NOT NULL ? ? DROP PROC dbo.Staff_insert; GO CREATE PROC dbo.Staff_insert ? ? @temptableName nvarchar(20)--臨時表名 AS BEGIN ? ? --用于實現循環(huán)的臨時表,intID列用于從1開始對記錄計數 ? ? CREATE TABLE #excelData(intID int identity(1,1),pjid char(6),userid char(6)); ? ? --將全局臨時表中的數據插入到臨時表中 ? ? INSERT INTO #excelData(pjid,userid) EXEC('SELECT pjid, userid FROM '+ @temptableName); ? ? --計算記錄的個數 ? ? SELECT @count= COUNT(1) FROM #excelData; ? ? --如果記錄存在尺迂,進入循環(huán) ? ? IF(@count > 0) ? ? BEGIN ? ? ? ? SET @i = 1;--循環(huán)變量 ? ? ? ? ? ? ? ? ? ? ? ?WHILE(@i <= @count) ? ? ? ? BEGIN ? ? ? ? ? ? -- 根據intid取出要操作的記錄 ? ? ? ? ? ? SELECT @pjid=pjid,@userid=userid FROM #excelData WHERE intID = @i; ? ? ? ? ? ? --其他操作 ? ? ? ? ? ? -- ? ? ? ? ? ? -- ? ? ? ? END ? ? END END 想把一個數據表里的某個字段篩選出來然后笤妙,循環(huán)的把值傳給另一個存儲過程冒掌,選擇使用了臨時表。 SQL代碼如下: CREATE TABLE #Temp_TABLE ( ID INT IDENTITY(1,1), TRANSID VARCHAR(30), --出庫單號 PRIMARY KEY (ID) ) INSERT INTO #Temp_TABLE SELECT TRANSID FROM A WHERE A.RPID='RP00913031200001'--從A表取出符合條件的數據插入到臨時表 DECLARE @TOTAL_COUNT INT,--臨時表記錄條數 @NOW_COUNT INT,--現在遍歷到哪條記錄 @TRID VARCHAR(30)--當前遍歷的transid SELECT @TOTAL_COUNT=COUNT(*) FROM #Temp_TABLE SET @NOW_COUNT=1; WHILE(@NOW_COUNT<=@TOTAL_COUNT) ?BEGIN ? ?SELECT @TRID=TRANSID FROM #Temp_TABLE ? ?WHERE ID=@NOW_COUNT --關鍵就在這(一切都因這個地方而不一樣了哦) ? ?EXEC proc_monprocess @TRID--傳給另一個存儲過程 ? ?SET @NOW_COUNT=@NOW_COUNT+1 ?END DROP TABLE #Temp_TABLE 有關表的數據插入 1蹲盘、把臨時表中的數據插入到另一個表中 insert into 表 select * from #temp 2股毫、把一個表中字段復制到臨時表中 select * into #temp from ? 表 where ... 3、本地臨時表的名稱以單個數字符號 (#) 打頭召衔;它們僅對當前的用戶連接是可見的铃诬; 4、當用戶從 SQL Server 實例斷開連接時被刪除苍凛。 5趣席、判斷臨時表是否存在 create proc temp(@tablename varchar(200)) as begin declare @exec varchar(8000) set @exec='use tempdb if exists(select * from sysobjects where id=object_id(''tempdb..'+@tablename+''')) select ''存在'' else select ''不存在''' exec (@exec) end
--計算一段時間內工作的天數
select dbo.f_workday('2014-06-01','2014-07-30')
create function ?f_workday(
-- 參數
@date_begin datetime, --計算開始日期
@date_end datetime ) ?--計算結束日期
returns int ?-- 返回值數據類型
as
begin
? ?declare ?@weeks ?int, ?-- 聲明變量
? ? ? ? ? ? @workday int
-- SQL語句(必須有return 變量或值)
---計算整周的工作天數
?select ?@weeks=(datediff (day ,@date_begin, @date_end)+1)/7, ? ? -- 計算開始和結束日期的之間的周數(完整的周)
? ? ? ? ?@workday=@weeks*5, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? --整周的工作天數----
? ? ? ? ?@date_begin=dateadd(day,@weeks*7,@date_begin) ? ? ? ? ? ?--最後一個不完整的周的工作天數
? ?while ?@date_begin<=@date_end
? ?begin
select @workday = case when (@@datefirst+datepart(weekday,@date_begin)-1)%7 between 1 and 5 then @workday+1
else @workday+1 end, @date_begin =@date_begin+1
end
return (@workday)
end
demo2:
-- 根據 questionID ?查詢 pName
create FUNCTION [dbo].[getPointNameByQuestionID](@questionID INT)
RETURNs varchar(256)
AS
BEGIN
? ?DECLARE @pName VARCHAR(256)
? ?SELECT DISTINCT TOP 1 @pName = p.pointName
FROM EXPORT_POINT_QUESTION_DHY pq
LEFT JOIN QZ_POINT p ON pq.pointID = p.pointID
WHERE pq.questionID = @questionID
? ?RETURN ISNULL(@pName , '其他' )
END
GO
select dbo.getPointNameByQuestionID(123);
demo3:
-----比較兩個值大小,返回小的----
create FUNCTION [dbo].[getMin]
(
? ?@num1 int,
? ?@num2 int
)
RETURNS int
as
BEGIN
declare @num int
if @num1>@num2
begin
set @num=@num2
end
else
begin
set @num=@num1
end
return @num
END
GO
? ?