Unfortunately, ISNUMERIC
does not evaluate formulae. You can try to write your own simple parser in a SQL function, but functions don't allow for any kind of error handling, so when you try to evaluate one of the non-numeric equations you'll run into issues.
Your best bet is likely to use whatever you're using to evaluate these equations to also perform this task - I assume that's in some sort of front end.
Since you aren't using a front end, here's the best that I can come up with for a straight SQL approach. First, create a stored procedure that can evaluate numeric only equations. This would be better as a function, but unfortunately functions don't allow TRY..CATCH
blocks, which is crucial for handling non-numeric equations. Here's an example of such a stored procedure:
CREATE PROCEDURE dbo.Check_Dynamic_Formula
@formula VARCHAR(60),
@result DECIMAL(10, 4) OUTPUT
AS
BEGIN
DECLARE
@sql NVARCHAR(100)
BEGIN TRY
SELECT @sql = 'SELECT @inner_result = ' + @formula
EXEC sp_executesql @sql, N'@inner_result DECIMAL(10, 4) OUTPUT', @inner_result = @result OUTPUT
END TRY
BEGIN CATCH
SELECT @result = NULL
END CATCH
END
Once you have that you can set up a CURSOR
to go through your table one row at a time (which is why a scalar function would have been much better since you could then avoid a CURSOR
). Check the output variable for each row in your table. If it's a NULL
then the stored procedure couldn't evaluate it.
Some important caveats...
There may be some instances where the evaluation becomes a numeric unintentionally - see @Sean Lange's comment to your question.
IMPORTANT This is highly susceptible to injection. I would not run this against any data that was available for a user to generate. For example, if you have users entering the formulae then they could make a SQL injection attack.
Finally, if any other error occurs in the TRY..CATCH
block, it will make it appear as if the row was a non-numeric. We're counting on the code failing to prove that it's non-numeric, which is a brittle approach. Any error could give you a false negative.