SQL SERVER 存储过程和事务(通过两个值自动计算第三个值并更新)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012571917/article/details/79913406

SQL SERVER 存储过程和事务

前提:再实际业务中,有一个需求,即是根据A字段和B字段计算C字段(批量的)考虑用的事务和WHILE循环,做成存储过程,然后作业,定时10分钟更新一次。其中A字段的值,又是根据其他4个字段为一组求的平均值。
那么该存储过程用到两次事务,事务1先计算A值,事务2再计算C值。注意两次事务的名称应该不同,不然可能有错误。

USE [MSIS]
GO

/* Object: StoredProcedure [dbo].[AutoUpByLeft] Script Date: 2018/4/12 14:34:12 */
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

– =============================================
– Author: zhangaz
– Create date: 2018/4/12
– Description: 同步分级
– =============================================
CREATE PROCEDURE [dbo].[AutoUpByLeft]
AS
BEGIN
IF OBJECT_ID(‘tempdb..#TEMPAL’) IS NOT NULL
DROP TABLE #TEMPA;
IF OBJECT_ID(‘tempdb..#TEMPBL’) IS NOT NULL
DROP TABLE #TEMPB;
IF OBJECT_ID(‘tempdb..#TEMPL’) IS NOT NULL
DROP TABLE #TEMP;
–1.先求平均值
WITH DETAIL
AS ( SELECT _CRF_Variable.Name ,
_CRFDataValue.CRF_Variable_Id ,
_CRFDataValue.ContentValue ,
_CRFDataValue.CRFData_Id ,
SUBSTRING(_CRF_Variable.Name, 0, 8) AS TempName
FROM dbo.CRFDataValue AS _CRFDataValue
INNER JOIN dbo.CRF_Variable AS _CRF_Variable ON _CRF_Variable.Id = _CRFDataValue.CRF_Variable_Id
WHERE _CRF_Variable.CRFForm_Id = 1287 AND Name LIKE ‘ ) , T A S ( S E L E C T C R F D a t a V a l u e . I d , C R F V a r i a b l e . N a m e , C R F D a t a V a l u e . C R F V a r i a b l e I d , C R F D a t a V a l u e . C o n t e n t V a l u e , C R F D a t a V a l u e . C R F D a t a I d , S U B S T R I N G ( C R F V a r i a b l e . N a m e , 0 , 8 ) A S T e m p N a m e F R O M d b o . C R F D a t a V a l u e A S C R F D a t a V a l u e I N N E R J O I N d b o . C R F V a r i a b l e A S C R F V a r i a b l e O N C R F V a r i a b l e . I d = C R F D a t a V a l u e . C R F V a r i a b l e I d W H E R E C R F V a r i a b l e . C R F F o r m I d = 1287 A N D N a m e L I K E 听力检查%平均%左%’
AND _CRFDataValue.ContentValue != ‘[]’
)

—-1.往#TEMPA中插入数据 先查出4个术后PTA 气导左和对应术后PTA 平均左
SELECT DETAIL.TempName AS aTempName ,
DETAIL.CRF_Variable_Id AS aCRF_Variable_Id ,
DETAIL.ContentValue AS aContentValue ,
DETAIL.CRFData_Id AS CRFData_Id ,
T.CRF_Variable_Id AS bCRF_Variable_Id ,
T.ContentValue AS bContentValue ,
DETAIL.TempName AS bTempName
INTO #TEMPAL
FROM DETAIL
INNER JOIN T ON T.CRFData_Id = DETAIL.CRFData_Id
AND T.TempName = DETAIL.TempName;
–2.往#TEMPB中插入数据
SELECT ROW_NUMBER() OVER ( ORDER BY CRFData_Id ) AS Id ,
AVG(CAST(#TEMPAL.aContentValue AS FLOAT)) AS TEMPAVG ,
bContentValue ,
CRFData_Id AS bCRFData_Id ,
bCRF_Variable_Id ,
COUNT(1) AS TEMPCOUNT
INTO #TEMPBL
FROM #TEMPAL
WHERE bContentValue IS NULL OR bContentValue=” –为空的计算平均值,已有平均值的不再计算
GROUP BY CRFData_Id ,
aTempName ,
bContentValue ,
bCRF_Variable_Id
HAVING COUNT(1) > 3;

–开启事务A,先计算并更新平均值((术后PTA 气导左500HZ+术后PTA 气导左1000HZ+术后PTA 气导左2000HZ+术后PTA 气导左4000HZ)/4=术后PTA 平均左)———–

BEGIN TRAN TL01 ;
DECLARE @ERRORA INT
SET @ERRORA = 0;
DECLARE @TEMPAVG INT
DECLARE @bCRFData_Id INT
DECLARE @bCRF_Variable_Id INT
DECLARE @J INT
SET @J=1
DECLARE @COUNTA INT
SELECT @COUNTA = COUNT(1)
FROM #TEMPBL;
WHILE(@COUNTA>=@J)
BEGIN
SELECT @TEMPAVG = TEMPAVG
FROM #TEMPBL
WHERE Id = @J;
SELECT @bCRFData_Id = bCRFData_Id
FROM #TEMPBL
WHERE Id = @J;
SELECT @bCRF_Variable_Id = bCRF_Variable_Id
FROM #TEMPBL
WHERE Id = @J;
UPDATE dbo.CRFDataValue SET ContentValue=@TEMPAVG WHERE CRFData_Id=@bCRFData_Id AND CRF_Variable_Id=@bCRF_Variable_Id
SET @J=@J+1
SET @ERRORA= @ERRORA + @@ERROR;
END
IF @ERRORA = 0
BEGIN
COMMIT TRAN TL01; –提交事务
END;
ELSE
BEGIN
ROLLBACK TRAN TL01; –回滚事务
END;

–根据平均值求分级
WITH SDSRIGHT
AS ( SELECT _CRF_Variable.Name ,
_CRFDataValue.CRF_Variable_Id ,
_CRFDataValue.ContentValue ,
_CRFDataValue.CRFData_Id ,
SUBSTRING(_CRF_Variable.Name, 0, 8) AS TempName
FROM dbo.CRFDataValue AS _CRFDataValue
INNER JOIN dbo.CRF_Variable AS _CRF_Variable ON _CRF_Variable.Id = _CRFDataValue.CRF_Variable_Id
WHERE _CRF_Variable.CRFForm_Id = 1287
AND Name LIKE ‘ ) , T A S ( S E L E C T C R F D a t a V a l u e . I d , C R F V a r i a b l e . N a m e , C R F D a t a V a l u e . C R F V a r i a b l e I d , C R F D a t a V a l u e . C o n t e n t V a l u e , C R F D a t a V a l u e . C R F D a t a I d , S U B S T R I N G ( C R F V a r i a b l e . N a m e , 0 , 8 ) A S T e m p N a m e F R O M d b o . C R F D a t a V a l u e A S C R F D a t a V a l u e I N N E R J O I N d b o . C R F V a r i a b l e A S C R F V a r i a b l e O N C R F V a r i a b l e . I d = C R F D a t a V a l u e . C R F V a r i a b l e I d W H E R E C R F V a r i a b l e . C R F F o r m I d = 1287 A N D N a m e L I K E 听力检查%平均%左%’
AND _CRFDataValue.ContentValue != ‘[]’
),
FENJI
AS ( SELECT _CRFDataValue.Id ,
_CRF_Variable.Name ,
_CRFDataValue.CRF_Variable_Id ,
_CRFDataValue.ContentValue ,
_CRFDataValue.CRFData_Id ,
SUBSTRING(_CRF_Variable.Name, 0, 8) AS TempName
FROM dbo.CRFDataValue AS _CRFDataValue
INNER JOIN dbo.CRF_Variable AS _CRF_Variable ON _CRF_Variable.Id = _CRFDataValue.CRF_Variable_Id
WHERE _CRF_Variable.CRFForm_Id = 1287
AND Name LIKE ‘$听力检查%术后AAO-HNS分级 左%’
)
SELECT ROW_NUMBER() OVER ( ORDER BY T.CRFData_Id ) AS Id ,
T.CRFData_Id ,
T.CRF_Variable_Id AS AVGPTACRF_Variable_Id ,
T.ContentValue AS AVGPTA ,
T.TempName ,
SDSRIGHT.CRFData_Id AS CRFData_Id2 ,
SDSRIGHT.CRF_Variable_Id AS SDSCRF_Variable_Id ,
SDSRIGHT.ContentValue AS SDS ,
SDSRIGHT.TempName AS TempName2 ,
FENJI.CRF_Variable_Id AS FENJICRF_Variable_Id ,
FENJI.ContentValue AS RIGHTFENJI
INTO #TEMP
FROM T
INNER JOIN SDSRIGHT ON T.CRFData_Id = SDSRIGHT.CRFData_Id
AND SDSRIGHT.TempName = T.TempName
INNER JOIN FENJI ON FENJI.CRFData_Id = SDSRIGHT.CRFData_Id
AND FENJI.TempName = SDSRIGHT.TempName
WHERE FENJI.ContentValue IS NULL OR FENJI.ContentValue=” –为空的分级更新赋值,有值的分级不在更新

–开启事务B,根据PAT和平均值,计算并更新分级字段
DECLARE @ERROR INT;
DECLARE @temp VARCHAR(50);
DECLARE @PAT NVARCHAR(50);
DECLARE @SDS NVARCHAR(50);
DECLARE @FENJI VARCHAR(50);
DECLARE @CRFData_Id INT;
DECLARE @TempName VARCHAR(50);
SET @ERROR = 0;
DECLARE @ISNUMBER INT;
DECLARE @FENJICRF_Variable_Id INT;
BEGIN TRAN TL02;
–声明事务
DECLARE @count INT;
DECLARE @I INT;
DECLARE @ISNUMBER2 INT;
SELECT @count = COUNT(1)
FROM #TEMP;
SET @I = 1;
–循环临时表
WHILE ( @count >= @I )
BEGIN
SELECT @PAT = AVGPTA
FROM #TEMP
WHERE Id = @I;
SELECT @SDS = SDS
FROM #TEMP
WHERE Id = @I;
SELECT @CRFData_Id = CRFData_Id
FROM #TEMP
WHERE Id = @I;
SELECT @FENJICRF_Variable_Id = FENJICRF_Variable_Id
FROM #TEMP
WHERE Id = @I;
PRINT ( ‘__’ + @SDS );
–SET @ISNUMBER = PATINDEX(‘%[^0-9|.|-|+]%’, CAST(@SDS AS CHAR));–返回0
–PRINT (‘—–’+@SDS)
–SET @ISNUMBER=PATINDEX(‘%[^0-9]%’, CAST(@SDS AS CHAR))
–当输入表达式得数为一个有效的整数、浮点数、money 或 decimal 类型,那么 ISNUMERIC 返回 1;否则返回 0。
SET @ISNUMBER = ISNUMERIC(CAST(@SDS AS CHAR));
SET @ISNUMBER2 = ISNUMERIC(CAST(@PAT AS CHAR));
PRINT ( @ISNUMBER );
IF @ISNUMBER <> 1
OR @ISNUMBER != 1
OR @ISNUMBER2 <> 1
OR @ISNUMBER2 != 1–不是数字直接跳出循环
BEGIN
SET @I = @I + 1;
CONTINUE;
END;
SET @SDS = CAST(@SDS AS DECIMAL);
SET @PAT = CAST(@PAT AS DECIMAL);
SET @FENJI = [dbo].[GetValue](@PAT, @SDS);–得到分级
UPDATE dbo.CRFDataValue
SET ContentValue = @FENJI
WHERE CRFData_Id = @CRFData_Id
AND CRF_Variable_Id = @FENJICRF_Variable_Id;
SET @I = @I + 1;
SET @ERROR = @ERROR + @@ERROR;
END;
IF @ERROR = 0
BEGIN
COMMIT TRAN TL02; –提交事务
END;
ELSE
BEGIN
ROLLBACK TRAN TL02; –回滚事务
END;
END;
GO

猜你喜欢

转载自blog.csdn.net/u012571917/article/details/79913406