Sql資料庫儲存過程傳值(傳遞資料表名,列名),sp_executesql函式的使用
遇到的專案需求是:對幾個不同的資料表和相應的欄位進行類似的操作,表的名稱和相關的列名可以作為儲存過程的引數傳遞,這樣可以使用遊標遍歷不同表格的不同的列,再使用相同函式求出返回值進行統一的處理。由於專案中表的資料龐大,關係複雜,此處做簡化處理,描述大致意思。(此處的資料庫是SQL資料庫)
資料準備
--建立使用者表 create table UserA( UserId varchar(32) NOT NULL, UserName varchar(32) NOT NULL, UserState int not null,--1:有效 0:無效 CONSTRAINT PK_UserA PRIMARY KEY NONCLUSTERED (UserId) )
--建立客戶表 create table CustomA( CustomId varchar(32) NOT NULL, CustomName varchar(32) NOT NULL, CustomState int not null,-- 1:有效 0:無效 CONSTRAINT PK_CustomA PRIMARY KEY NONCLUSTERED (CustomId) )
--建立統計表 create table Calculate( Id varchar(32) NOT NULL, TableName varchar(32) NOT NULL, TotalQuantity int not null, EffectQuantity int not null, CONSTRAINT PK_Calculate PRIMARY KEY NONCLUSTERED (Id) )
--新增測試資料 INSERT INTO UserA VALUES ('1', '使用者1', '1'); INSERT INTO UserA VALUES ('2', '使用者2', '1'); INSERT INTO UserA VALUES ('3', '使用者3', '0'); INSERT INTO UserA VALUES ('4', '使用者4', '1'); INSERT INTO UserA VALUES ('5', '使用者5', '1');
INSERT INTO CustomA VALUES ('1', '客戶1', '0'); INSERT INTO CustomA VALUES ('2', '客戶2', '1'); INSERT INTO CustomA VALUES ('3', '客戶3', '0'); INSERT INTO CustomA VALUES ('4', '客戶4', '1'); INSERT INTO CustomA VALUES ('5', '客戶5', '1'); INSERT INTO CustomA VALUES ('6', '客戶6', '0');
INSERT INTO Calculate VALUES ('1', 'CustomA', '0', '0'); INSERT INTO Calculate VALUES ('2', 'UserA', '0', '0');
實現目標
統計表UserA和表CustomA裡面狀態是1的資料總數(EffectQuantity)和全部數量(Quantity),統計完成更新到表Calculate裡面。
實現步驟
一、寫出相關的SQL查詢語句(單一步驟)
--獲取使用者表的有效數量和全部數量 select count(case when UserState=1 then 1 else null end) as EffectQuantity,count(*) as Quantity from UserA
--獲取客戶表的有效數量和全部數量 select count(case when CustomState=1 then 1 else null end) as EffectQuantity,count(*) as Quantity from CustomA
--更新統計表的資料 update Calculate set TotalQuantity=1, EffectQuantity=1 where TableName='CustomA'
二、組合成為儲存過程
--把這兩個查詢結果更新到統計表 create procedure SP_Calculate @p_ColumnName varchar(50), @p_TableName varchar(50) AS BEGIN declare @sql nvarchar(1000),@updatesql nvarchar(1000), @qty int,--總人數 @effectqty int;--有效人數 --拼接查詢語句 set @sql='select @effectqty=count(case when '[email protected]_ColumnName+'=1 then 1 else null end),' +'@qty=count(*) from '[email protected]_TableName ; exec sp_executesql @sql,N'@effectqty int out,@qty int out',@effectqty out,@qty out; PRINT (convert(varchar(11),@effectqty)+','+convert(varchar(11),@qty)+','[email protected]_TableName) set @updatesql='update Calculate set [email protected], [email protected] where [email protected]'; exec sp_executesql @updatesql,N'@qty int,@effectqty int,@tablename varchar(50)',@qty,@effectqty,@p_TableName; --引數的順序必須一一對應,如果順序不一致需要顯式標註 (如下顯示) --exec sp_executesql @updatesql,N'@qty int,@effectqty int,@tablename varchar(50)',@[email protected],@[email protected],@[email protected]_TableName; END
--更新Calculate表中客戶的資料 EXEC SP_Calculate @p_ColumnName= 'CustomState',@p_TableName = 'CustomA';
--更新Calculate表中使用者的資料 EXEC SP_Calculate @p_ColumnName= 'UserState',@p_TableName = 'UserA';
--儲存過程 統計表UserA的總數和有效數量
三、其實還有多個這樣的表,現在把這些放在一個儲存過程裡面統一管理,如下實現在儲存過程內部呼叫儲存過程,要是增加了新的類似的表格,只需要修改下面的儲存過程就可以了。
alter procedure SP_CalculateCollection AS BEGIN EXEC SP_Calculate @p_ColumnName= 'CustomState',@p_TableName = 'CustomA'; EXEC SP_Calculate @p_ColumnName= 'UserState',@p_TableName = 'UserA'; END
EXEC SP_CalculateCollection