November 23, 2016 at 9:50 pm
I have the table contents as shown in this picture:
screenshot
The formula column contains the the column names as variables in the formula expression.
I am trying to get a computed column Score corresponding for each emp_id,Tsk_id and processed date which would be calculated dynamically based on the formulae given in the formula column and push it to a temp table
I have tried to achieve it by dynamic SQL within a cursor using the below code which has been successful. Can Anyone suggest a better way to do it, maybe using a CTE or something ?
DECLARE @EMP_ID nVARCHAR(255)
DECLARE @TSK_ID nVARCHAR(255)
DECLARE @PROCESSEDDATE nVARCHAR(255)
DECLARE @SQLCMD nVARCHAR(max)
DECLARE @SQLTEXT nvarchar(max)
DECLARE db_cursor CURSOR FOR
SELECT EMP_ID,TSK_ID,PROCESSEDDATE from dbo.[Formula_Cal] group by EMP_ID,TSK_ID,PROCESSEDDATE
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @EMP_ID,@TSK_ID,@PROCESSEDDATE
WHILE @@FETCH_STATUS = 0
BEGIN
Set @SQLTEXT = (Select formula from dbo.[Formula_Cal] where EMP_ID=@EMP_ID and TSK_ID =@TSK_ID and PROCESSEDDATE=@PROCESSEDDATE )
Set @SQLCMD ='select emp_id,TSK_ID,convert(decimal(18,2),( ' +@SQLTEXT+ ')) As Score FROM [Formula_Cal] where TSK_ID = '+@TSK_ID+' and EMP_ID = '+@EMP_ID
--Select @SQLTEXT
--Select @SQLCMD
insert into dbo.TMP_ACHSCR(emp_id,TSK_id,Score)
Exec sp_executesql @SQLCMD
FETCH NEXT FROM db_cursor INTO @EMP_ID,@TSK_ID,@PROCESSEDDATE
END
CLOSE db_cursor
DEALLOCATE db_cursor
November 23, 2016 at 10:00 pm
How many possible combinations are there for "formula"? You could write a CASE statement that determined which formula to use to calculate the answer... surely must be faster than a cursor...
November 23, 2016 at 10:03 pm
there is no defined set of formulas used here , it may vary for every row. So writing formulas into a case would ask of hardcoding , aim is to do the calculation dynamically using the variable column names in the table
November 24, 2016 at 10:37 am
bineet.dungdung (11/23/2016)
there is no defined set of formulas used here , it may vary for every row. So writing formulas into a case would ask of hardcoding , aim is to do the calculation dynamically using the variable column names in the table
You do have a fixed number of column names (at this point), so this will do the job.
Some of the more experienced guys may be able to improve on it.
CREATE TABLE #Data (
EMP_ID INT NOT NULL
, TSK_ID INT NOT NULL
, PROCESSEDDATE DATE NOT NULL
, ColA DECIMAL(6, 2) NOT NULL
, ColB DECIMAL(6, 2) NOT NULL
, ColC DECIMAL(6, 2) NOT NULL
, Formula VARCHAR(2000) NOT NULL
, Result DECIMAL(6, 2)
-- Note that this key is used in the dynamic SQL for the join
, PRIMARY KEY CLUSTERED (EMP_ID, TSK_ID)
);
INSERT INTO #Data ( EMP_ID, TSK_ID, PROCESSEDDATE, ColA, ColB, ColC, Formula )
SELECT src.EMP_ID, src.TSK_ID, src.PROCESSEDDATE, src.ColA, src.ColB, src.ColC, src.Formula
FROM (VALUES ( 719200, 66, '2016-10-11', 3.00, 109.00, 117.00, '@ColA/@ColB*100' )
, ( 719200, 67, '2016-10-11', 3.00, 109.00, 117.00, '@ColB' )
, ( 719200, 68, '2016-10-11', 3.00, 109.00, 117.00, '@ColC' )
, ( 719200, 69, '2016-10-11', 3.00, 109.00, 117.00, '(@ColC/@ColA)*100' )
, ( 728836, 66, '2016-10-11', 0.00, 67.00, 52.00, '(@ColA/@ColC)*100' )
) src(EMP_ID, TSK_ID, PROCESSEDDATE, ColA, ColB, ColC, Formula);
GO
DECLARE
@Sprtr VARCHAR(MAX) = ' union all '
, @Lf CHAR(1) = CHAR(10)
, @sql VARCHAR(MAX)
SELECT @sql = 'WITH cteResults (EMP_ID, TSK_ID, Rslt) AS (' + @Lf
+ STUFF( (
SELECT @Sprtr + 'SELECT ' + CONVERT(VARCHAR(20), d.EMP_ID)
+ ', ' + CONVERT(VARCHAR(20), d.TSK_ID)
+ ', ' + REPLACE(
REPLACE(
REPLACE(d.Formula
, '@ColA', CONVERT(VARCHAR(20), d.ColA))
, '@ColB', CONVERT(VARCHAR(20), d.ColB))
, '@ColC', CONVERT(VARCHAR(20), d.ColC))
+ @Lf
FROM #Data AS d
FOR XML PATH('')
), 1, LEN(@Sprtr), '')
+ ')' + @Lf
+ 'SELECT d.EMP_ID, d.TSK_ID, d.PROCESSEDDATE, d.ColA, d.ColB, d.ColC, d.Formula, r.Rslt' + @Lf
+ 'FROM #Data AS d' + @Lf
+ 'INNER JOIN cteResults AS r ON d.EMP_ID = r.EMP_ID AND d.TSK_ID = r.TSK_ID' + @Lf
+ 'ORDER BY d.EMP_ID, d.TSK_ID;'
--PRINT (@SQL);
EXEC (@SQL);
Edit: Formatted REPLACE for better readability.
Viewing 4 posts - 1 through 3 (of 3 total)
You must be logged in to reply to this topic. Login to reply