1. 程式人生 > >Sql資料庫儲存過程傳值(傳遞資料表名,列名),sp_executesql函式的使用

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