是否可以制作通过公式提交计算的表格或视图 ,在其他字段中指定为文本?
例如:
A B C formula value
- - - - -------- -----
1. 2 1 3 (A+B)*C 9
2. 100 null 2 A/C 50
感谢和最好的问候
答案 0 :(得分:1)
这很有意思。我不确定这是最有效的方法,但这是一个有效的解决方案...
CREATE TABLE tmpMaths (ID INT IDENTITY(1,1), A INT, B INT, C INT, formula VARCHAR(255), formulaResult FLOAT);
INSERT tmpMaths (A, B, C, formula) VALUES (2, 1, 3, '(A+B)*C')
, (100, NULL, 2, 'A/C/C/C/A');
DECLARE @Results TABLE (ID INT, Result FLOAT);
DECLARE @SQL2 VARCHAR(MAX) = '';
SELECT @SQL2 += ' UNION ALL SELECT ' + CAST(ID AS VARCHAR(255)) + ' ID, 1.0 * '
+ REPLACE(REPLACE(REPLACE(formula, 'A', ISNULL(A, '')), 'B', ISNULL(B, '')), 'C', ISNULL(C, ''))
+ ' Result FROM tmpMaths WHERE ID = ' + CAST(ID AS VARCHAR(255))
FROM tmpMaths;
SELECT @SQL2 = STUFF(@SQL2, 1, 11, '');
INSERT @Results (ID, Result)
EXEC(@SQL2);
UPDATE M SET formulaResult = R.Result --SELECT M.ID, A, B, C, formula, Result
FROM tmpMaths M
JOIN @Results R ON R.ID = M.ID;
SELECT * FROM tmpMaths;
DROP TABLE tmpMaths;
如果您不知道所有列名称,那么类似下面的内容会更复杂,但无论如何......(基本上它通过动态SQL获取列名称):
CREATE TABLE tmpMaths (ID INT IDENTITY(1,1), A INT, B INT, C INT, formula VARCHAR(255));
INSERT tmpMaths (A, B, C, formula) VALUES (2, 1, 3, '(A+B)*C')
, (100, NULL, 2, 'A/C/C/C/A');
DECLARE @replacecount INT = (
SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'tmpMaths'
AND COLUMN_NAME NOT IN ('ID', 'formula')) -- get the count of columns, unnecessary if it's always just 3 (A, B, C)
, @replace VARCHAR(MAX) = ''
, @cols VARCHAR(MAX) = '';
SELECT @replace += ', ''' + COLUMN_NAME + ''', ISNULL(' + COLUMN_NAME + ', ''''))' -- for replacing the column names in the formula
, @cols += ', ' + COLUMN_NAME -- for selecting the columns in output, unnecessary if it's always just A, B, C
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'tmpMaths'
AND COLUMN_NAME NOT IN ('ID', 'formula');
DECLARE @selectreplace NVARCHAR(MAX) = REPLICATE('REPLACE(', @replacecount) + 'formula' + @replace; -- e.g. REPLACE(REPLACE(REPLACE(formula, 'A', A), 'B', B), 'C' C)
IF OBJECT_ID('tempdb..#tmpEvaluated') IS NOT NULL DROP TABLE #tmpEvaluated;
CREATE TABLE #tmpEvaluated (ID INT, Evaluated VARCHAR(255));
DECLARE @SQL VARCHAR(MAX) = 'INSERT #tmpEvaluated (ID, Evaluated) SELECT ID, ' + @selectreplace + ' FROM tmpMaths';
EXEC(@SQL); -- produces the formula with numbers instead of column names
IF OBJECT_ID('tempdb..#tmpResults') IS NOT NULL DROP TABLE #tmpResults;
CREATE TABLE #tmpResults (ID INT, Result FLOAT);
DECLARE @SQL2 VARCHAR(MAX) = '';
SELECT @SQL2 += ' UNION ALL SELECT ' + CAST(ID AS VARCHAR(255)) + ' ID, 1.0 * ' + Evaluated + ' Result FROM #tmpEvaluated WHERE ID = ' + CAST(ID AS VARCHAR(255))
FROM #tmpEvaluated;
SELECT @SQL2 = STUFF(@SQL2, 1, 11, '');
INSERT #tmpResults (ID, Result)
EXEC(@SQL2); -- gets the result of the formula with numbers in it (a series of UNION ALL statements)
PRINT @SQL2;
DECLARE @output VARCHAR(MAX) = 'SELECT M.ID' + @cols + ', formula, result FROM tmpMaths M JOIN #tmpResults R ON R.ID = M.ID';
EXEC(@output);
DROP TABLE tmpMaths;