首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >计算数学字符串中的空值,而不将其替换为0 PL/SQL

计算数学字符串中的空值,而不将其替换为0 PL/SQL
EN

Stack Overflow用户
提问于 2017-06-14 16:45:04
回答 2查看 213关注 0票数 0

我需要计算存储在字符串中的数学表达式的结果(例如:'A*(B+C)+(D*E)+F+G*(H+I)')。字符串可以包含任何数学运算符。

我的程序( PL/SQL过程)的第一步是将变量替换为它们的值(可以是NULL)

但我不能将NULL值替换为零,因为我需要区分总结果是NULL还是0

示例#1:

我希望结果为NULL,而不是0。

代码语言:javascript
运行
复制
NULL*(B+C)+(NULL*10)+NULL+5*(NULL+NULL)

示例#3:

我希望结果是0

代码语言:javascript
运行
复制
NULL*(B+C)+(NULL*10)+0+5*(NULL+NULL)

示例2:

我预计会有99个结果

代码语言:javascript
运行
复制
NULL*(B+C)+(NULL*10)+99+5*(NULL+NULL)  

有没有办法动态地做到这一点?数学表达式可以是任何其他类型('A*B+C*D+E*G''A*(B+C)+D*(E+F)'或简单A*BA+B+C)。

如果没有括号,则必须像在标准计算中一样考虑数学运算符的优先级。

在替换所有值并从空值中清除表达式之后,我使用execute immediate来计算最终结果。

谢谢你的帮忙!

EN

回答 2

Stack Overflow用户

发布于 2017-06-14 18:07:23

您可以使用动态SQL (在计算中使用Oracle的NULL值逻辑-因此可以使用NULL + anything = NULLNULL * anything = NULL):

代码语言:javascript
运行
复制
DECLARE
  SUBTYPE VARIABLE_TYPE IS VARCHAR2(5);
  TYPE VARIABLE_MAP IS TABLE OF NUMBER INDEX BY VARIABLE_TYPE;

  variables  VARIABLE_MAP;
  expression VARCHAR2(4000) := 'A*(B+C)+(D*E)+F+G*(H+I)';
  v          VARIABLE_TYPE;
  e          VARCHAR2(4000);
  r          NUMBER;
BEGIN
  -- Populate the variables values
  variables('A') := 1;
  variables('B') := 2;
  variables('C') := 3;
  variables('D') := 4;
  variables('E') := 5;
  variables('F') := 6;
  variables('G') := 7;
  variables('H') := 8;
  variables('I') := 9;

  -- Replace the variables with their values:
  e := expression;
  v := variables.FIRST;
  WHILE v IS NOT NULL LOOP
    e := REPLACE( e, v, COALESCE( TO_CHAR( variables(v) ), 'NULL' ) );
    v := variables.NEXT(v);
  END LOOP;

  -- Perform the calculation
  EXECUTE IMMEDIATE 'BEGIN :1 := ' || e || '; END;' USING IN OUT r;

  -- Output the result
  DBMS_OUTPUT.PUT_LINE( r );
END;
/

输出

代码语言:javascript
运行
复制
150
票数 0
EN

Stack Overflow用户

发布于 2017-06-14 16:59:36

这里有一个很好的函数https://social.msdn.microsoft.com/Forums/sqlserver/en-US/434baca4-56dd-4ba3-896c-a04e2d29b5ef/stack-with-sql-server?forum=transactsql

但这是针对SQL Server的。您必须调整它以处理诸如-*、/、(& )之类的运算符。您可以在此处管理您的空值。

基本上,你必须将这个表达式放入一个堆栈中&评估(Pop) &求解你的表达式。

代码语言:javascript
运行
复制
create table dbo.Stack
(
stkID int identity(1,1) not null primary key,
stkData varchar(50) not null,
)
go

create procedure dbo.spStackPush
(
@stkData varchar(10)
)
as
begin
set nocount on
insert into Stack (stkData) values (@stkData)
if @@error <> 0 raiserror('Could not push to stack', 16, 1)
return 0
end
go

create procedure dbo.spStackPop
(
@stkData varchar(10) output
)
as
begin
set nocount on
declare @stkID int
select
@stkData = stkData,
@stkID = stkID
from dbo.Stack
where stkID = (select max(stkID) from dbo.Stack)

delete from dbo.Stack where stkID = @stkID
return 0
end
go

create procedure dbo.spStackEvaluate
(
@stkData varchar(10) output
)
as
begin
set nocount on
declare @stkLeft varchar(10)
declare @stkRight varchar(10)
declare @stkNext varchar(10)

exec dbo.spStackPop @stkData output

if @stkData = '+'
begin
exec dbo.spStackPop @stkLeft output
exec dbo.spStackPop @stkRight output

set @stkData = cast(@stkLeft as int) + cast(@stkRight as int)
end

if exists(select 1 from dbo.Stack)
begin
exec dbo.spStackPop @stkNext output
exec dbo.spStackPush @stkData
exec dbo.spStackPush @stkNext
exec dbo.spStackEvaluate @stkData output
end

return 0
end
go

-- Test script
delete dbo.Stack

declare @stkData varchar(10)

exec dbo.spStackPush '10'
exec dbo.spStackPush '+'
exec dbo.spStackPush '20'
exec dbo.spStackPush '+'
exec dbo.spStackPush '30'
exec dbo.spStackPush '40'
exec dbo.spStackPush '+'

exec dbo.spStackEvaluate @stkData output
print @stkData 
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44539791

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档