Hi,
I need to implement a stack using Sql Server.
The basic table is simple:-
id (int), val (char(10)).
Basically I want a recursive EvaluateStack stored procedure. This should select the topmost value from the stack, and then either return it or (in the case of an operator) recursively call itself in order to get a left hand and a righthand operator. So:
(pseudo-code)
SELECT val FROM STACK WHERE id=@Count
CASE WHEN val="+"
lhs=EXEC EvaluateStack
rhs=EXEC EvaluateStack
return lhs+rhs
SELECT @Count=@Count-1
Etc. etc.
The problem is, being a bit rusty with Sql Server, can anyone give me some pointers how to best implement the conditional logic
I.e. I want to evaluate the value in the row at the bottom of the table, then if it is an operator EXECUTE this stored procedure again.
Thanks in advance. Another peculiarity is that '+' evaluates to true using Sql Server's ISNUMERIC function.

Stack With SQL Server
Sanjay_msdn
It isn't beautiful but at least it show that it's possible. There is all possible kind of errors and concurrency issues to consider but it works for getting a sum. I would definatly seek other solutions, even as a humble lackey.
This is not reverse polish notation, that you have to figure out. This just demonstrates a stack and recursive calling to process it in a totally proprietary way.
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
Sephiroth84
Do two procedures that do the essential stack basics to add some abstraction. spStackPush and spStackPop.
Then you use another procedure spStackEvaluate that you call. In pseudecode without error handling maybe something like this. There is no need for recursion to do what you seem to want to do.
procedure spStackEvaluate
@val output
begin
execute spStackPop @val output
if @val = '+'
begin
execute spStackPop @leftval output
execute spStackPop @rightval output
set @val = cast(@leftval as numeric) + cast(@leftval as numeric)
end
end
oceanhai
I choose not to call spStackEvaluate for spStackPop because it is not only popping the stack, it is doing much more. Stack operations are usually push and pop so to at least not to try confuse myself I tried to stick to those basic operations.
Rename spStackPop to spStackPopOne and stStackEvaluate to spStackPop and you will be more close to what you describe. It's just names so it does not matter much.
Guy Serfaty
I am not dictating the requirements in this case.
Once again, I DO need to implement a stack in Sql and I would be incredibly grateful if anyone has any advice on the recursive call mechanism needed to get this working (i.e. if the value popped of the stack is an operator, to gather the next two values (operands) and operate on them).
Vossekop
--
Adam Machanic
Pro SQL Server 2005, available now
http://www..apress.com/book/bookDisplay.html bID=457
--
Xinil
The stack in question is basically being used to hold the values for a reverse polish notation calculation on certain values in the database.
So, while a formula could be as simple as 2,2,+, it could also take a more complex form...and even with sthg not that much more complex like 10,10,+,2,/: recursion is needed. Because, say you evaluate '/'. Naturally you then need two operands. The problem is you are going to get one operand (2 in this case) and then another operator, engendering the need for a recursive call in order to get a valid operand.
I'm sure your stomach is churning at doing it this way, so let me underline again that this is not a design of my choice, I am a humble lackey.
Joseph Lee
Andreas,
Many thanks for this. This is a good way towards a solution, although as I say I believe the call to Pop must be replaced with a recursive call to Evaluate. That way if it hits an operator it will first fetch two operands.
But that's the bit of code that is proving tricky, and somewhat undocumented...