Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 Old Forums
 CLOSED - General SQL Server
 Can this be done? (Difficulty rating 10) I think!

Author  Topic 

MikeB
Constraint Violating Yak Guru

387 Posts

Posted - 2004-04-13 : 16:39:21
I have a stored procedure that will return the following string:

(108 * 4) + (((36 - 4) * (5)) * 2)


Are there any already written functions/stored procedures that can parse and compute the above string?

If not, can someone help me get started on this?

Mike B

drymchaser
Aged Yak Warrior

552 Posts

Posted - 2004-04-13 : 16:42:27
Let me guess. This is produced dynamically.
Go to Top of Page

tkizer
Almighty SQL Goddess

38200 Posts

Posted - 2004-04-13 : 16:44:16
Does this not work:

create proc test
(@var1 varchar(500) output)

as

set @var1 = (108 * 4) + (((36 - 4) * (5)) * 2)

return



declare @int int

exec test @int output

print @int


drop proc test


So when you execute it, it does the computation since you are using INT.



Tara
Go to Top of Page

MikeB
Constraint Violating Yak Guru

387 Posts

Posted - 2004-04-13 : 17:30:58
I can get your example to work, but not the real thing. It gives the error : "Error converting data type varchar to float."


USE NORTHWIND
GO

create proc test
@input varchar(500) output,
@var1 varchar(500) output

as

set @var1 = @input

return

GO

declare @int int, @Input varchar(500)

set @Input = '(108 * 4) + (((36 - 4) * (5)) * 2)'
exec test @Input, @int output

print @int
GO

drop proc test
GO


The expression is created dynamically using:


SELECT @cResult AS Formula

DECLARE AttributeCursor CURSOR FOR
SELECT sa.Attribute,
av.AttributeValue
FROM tbProductTemplateAttributeValues AS av INNER JOIN tbShapeAttributes AS sa
ON av.fkAttributeID = sa.AttributeID
WHERE av.fkTemplateID = @iTemplate

OPEN AttributeCursor
FETCH NEXT FROM AttributeCursor INTO @cAttribute, @fAttribute
while(@@FETCH_STATUS = 0)
BEGIN
SELECT @cResult = REPLACE(@cResult, @cAttribute, CAST(@fAttribute AS VarChar)) FETCH NEXT FROM AttributeCursor INTO @cAttribute, @fAttribute
END

CLOSE AttributeCursor
DEALLOCATE AttributeCursor
GO


The SELECT in red above is how the expression is created.

Mike B
Go to Top of Page

MikeB
Constraint Violating Yak Guru

387 Posts

Posted - 2004-04-13 : 19:25:03
You can use the following DDL and DML to see exactly what I am trying to do:


USE NORTHWIND
GO

SET NOCOUNT ON
CREATE TABLE [dbo].[tbProductCodes] (
[ProductCode] [int] NOT NULL ,
[fkAccountID] [int] NOT NULL ,
[Product] [varchar] (50) NOT NULL ,
[fkShapeID] [int] NOT NULL
) ON [PRIMARY]
GO

INSERT INTO tbProductCodes (ProductCode, fkAccountID, Product, fkShapeID)
SELECT 2001, 1, 'New Product', 1
GO

CREATE TABLE [dbo].[tbProductTemplateAttributeValues] (
[fkTemplateID] [int] NOT NULL ,
[fkAttributeID] [int] NOT NULL ,
[AttributeValue] [float] NOT NULL
) ON [PRIMARY]
GO

INSERT INTO tbProductTemplateAttributeValues (fkTemplateID, fkAttributeID, AttributeValue)
SELECT 1, 1, 108 UNION ALL
SELECT 1, 2, 36 UNION ALL
SELECT 1, 3, 4 UNION ALL
SELECT 1, 4, 5 UNION ALL
SELECT 1, 5, 2
GO

CREATE TABLE [dbo].[tbProductTemplates] (
[TemplateID] [int] NOT NULL ,
[fkProductCode] [int] NOT NULL ,
[Template] [varchar] (50) NOT NULL ,
[fkMixID] [int] NULL
) ON [PRIMARY]
GO

INSERT INTO tbProductTemplates (TemplateID, fkProductCode, Template, fkMixID)
SELECT 1, 2001, 'ProductTemplate', 1
GO

CREATE TABLE [dbo].[tbShapeAttributes] (
[AttributeID] [int] NOT NULL ,
[fkShapeID] [int] NOT NULL ,
[Attribute] [varchar] (50) NOT NULL
) ON [PRIMARY]
GO

INSERT tbShapeAttributes (AttributeID, fkShapeID, Attribute)
SELECT 1, 1, 'Width' UNION ALL
SELECT 2, 1, 'Height' UNION ALL
SELECT 3, 1, 'Flange' UNION ALL
SELECT 4, 1, 'Leg' UNION ALL
SELECT 5, 1, 'Count'
GO

CREATE TABLE [dbo].[tbShapes] (
[ShapeID] [int] NOT NULL ,
[Shape] [varchar] (50) NOT NULL ,
[Formula] [varchar] (100) NULL
) ON [PRIMARY]
GO

INSERT INTO tbShapes (ShapeID, Shape, Formula)
SELECT 1, 'Double T', '(Width * Flange) + (((Height - Flange) * Leg) * Count)'
GO

CREATE PROCEDURE usp_shapes_GetCrossSection

@iTemplate int,
@cResult varchar (500) OUTPUT

AS

declare @cAttribute varchar(50),
@fAttribute float

-- Get the formula for the templates shape
SELECT @cResult = s.Formula
FROM tbShapes AS s INNER JOIN tbProductCodes AS pc
ON s.ShapeID = pc.fkShapeID
INNER JOIN tbProductTemplates AS pt
ON pc.ProductCode = pt.fkProductCode
WHERE pt.TemplateID = @iTemplate

SELECT @cResult AS Formula

DECLARE AttributeCursor CURSOR FOR
SELECT sa.Attribute,
av.AttributeValue
FROM tbProductTemplateAttributeValues AS av INNER JOIN tbShapeAttributes AS sa
ON av.fkAttributeID = sa.AttributeID
WHERE av.fkTemplateID = @iTemplate

OPEN AttributeCursor
FETCH NEXT FROM AttributeCursor INTO @cAttribute, @fAttribute
while(@@FETCH_STATUS = 0)
BEGIN
SELECT @cResult = REPLACE(@cResult, @cAttribute, CAST(@fAttribute AS VarChar))
FETCH NEXT FROM AttributeCursor INTO @cAttribute, @fAttribute
END

SELECT @cResult AS NewFormula

CLOSE AttributeCursor
DEALLOCATE AttributeCursor
GO

-- Test stored proc

declare @iTemplate int, @fResult float

SET @iTemplate = 1
EXECUTE usp_shapes_GetCrossSection @iTemplate, @fResult OUTPUT
SELECT @fResult AS Result
GO

drop table [dbo].[tbProductCodes]
GO

drop table [dbo].[tbProductTemplateAttributeValues]
GO

drop table [dbo].[tbProductTemplates]
GO

drop table [dbo].[tbShapeAttributes]
GO

drop table [dbo].[tbShapes]
GO

DROP PROCEDURE usp_shapes_GetCrossSection
GO



Mike B
Go to Top of Page

tkizer
Almighty SQL Goddess

38200 Posts

Posted - 2004-04-13 : 19:41:52
I can't get it to work either. Why can't you compute the value inside the stored proc? Why do you need to output a formula? Can't you just refer to the column names in the computation?

SELECT (Column1 + Column2)/(ColumnA - ColumnB)
FROM Table1

Tara
Go to Top of Page

MikeB
Constraint Violating Yak Guru

387 Posts

Posted - 2004-04-13 : 19:57:54
quote:
Originally posted by tduggan

I can't get it to work either. Why can't you compute the value inside the stored proc? Why do you need to output a formula? Can't you just refer to the column names in the computation?

SELECT (Column1 + Column2)/(ColumnA - ColumnB)
FROM Table1

Tara



This is a generic procedure among all shapes in the tbShapes table.
The shapes are setup in the front end. The user would create a shape, set the formula, and ensure he/she adds attributes with names matching those in the formula. There has to be a way to do it.

Mike B
Go to Top of Page

byrmol
Shed Building SQL Farmer

1591 Posts

Posted - 2004-04-13 : 20:53:39
Ok I see the problem here..

In your example you use @fResult float instead of @fResult varchar(500)

This works....

declare @iTemplate int, @fResult varchar(500)
SET @iTemplate = 1
EXECUTE usp_shapes_GetCrossSection @iTemplate, @fResult OUTPUT
SELECT @fResult = 'SELECT ' + @fResult
EXEC (@fResult)


DavidM

"If you are not my family or friend, then I will discriminate against you"
Go to Top of Page

Lavos
Posting Yak Master

200 Posts

Posted - 2004-04-13 : 21:08:54
[Previous Post Deleted]

Crap, I A) need to read the other replies closer, B) not accidently hit submit reply before I get everything typed in when I'm switching between windows to double check code, and C) post quick cause otherwise someone will snipe me (like what happened with my first post that I deleted.) (and probably D) stop editing posts over and over after posting)

Here was my solution, copying the beginning parts from DavidM :)


declare @iTemplate int, @fResult varchar(500)

SET @iTemplate = 1
EXECUTE usp_shapes_GetCrossSection @iTemplate, @fResult OUTPUT

DECLARE @stmt nvarchar(4000)
DECLARE @param nvarchar(4000)
DECLARE @Eval int

SET @stmt='SET @StmResult = ' + @fResult
SET @Param='@StmResult int out'

EXEC sp_executesql @stmt, @Param, @Eval OUT

SELECT @Eval



----------------------
"O Theos mou! Echo ten labrida en te mou kephale!"

"Where theres a will, theres a kludge." - Ken Henderson
Go to Top of Page

MikeB
Constraint Violating Yak Guru

387 Posts

Posted - 2004-04-13 : 21:21:52
quote:
Originally posted by byrmol

Ok I see the problem here..

In your example you use @fResult float instead of @fResult varchar(500)

This works....

declare @iTemplate int, @fResult varchar(500)
SET @iTemplate = 1
EXECUTE usp_shapes_GetCrossSection @iTemplate, @fResult OUTPUT
SELECT @fResult = 'SELECT ' + @fResult
EXEC (@fResult)


DavidM

"If you are not my family or friend, then I will discriminate against you"


Awsome, pure genius, I didn't even think of dynamic sql. Thank you very much.

This, however, will return the result as a result set, is there a way to return this as an output parameter?


CREATE PROCEDURE

@iTemplate int,
@fResult float OUTPUT,

AS

declare @cResult varchar(500)

EXECUTE usp_shapes_GetCrossSection @iTemplate, @cResult OUTPUT
SELECT @fResult = 'SELECT @fResult = ' + @cResult
EXEC (@fResult)

GO

Of course, the @fResult in red above causes the error:
Must declare the variable '@fResult'.

Any thoughts on this?

Mike B
Go to Top of Page

byrmol
Shed Building SQL Farmer

1591 Posts

Posted - 2004-04-13 : 21:26:43
Mike,

Lavos has gone the last mile for you... Use his code!!! sp_executesql is designed for this as it can handle OUTPUT parameters....

DavidM

"If you are not my family or friend, then I will discriminate against you"
Go to Top of Page

MikeB
Constraint Violating Yak Guru

387 Posts

Posted - 2004-04-13 : 21:33:29
quote:
Originally posted by Lavos

[Previous Post Deleted]

Crap, I A) need to read the other replies closer, B) not accidently hit submit reply before I get everything typed in when I'm switching between windows to double check code, and C) post quick cause otherwise someone will snipe me (like what happened with my first post that I deleted.) (and probably D) stop editing posts over and over after posting)

Here was my solution, copying the beginning parts from DavidM :)
----------------------
"O Theos mou! Echo ten labrida en te mou kephale!"

"Where theres a will, theres a kludge." - Ken Henderson


Perfection, simply put, thank you very much for your help!

Mike B
Go to Top of Page
   

- Advertisement -