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
 SQL Server 2000 Forums
 Transact-SQL (2000)
 Varialble table in string select

Author  Topic 

hog
Constraint Violating Yak Guru

284 Posts

Posted - 2005-06-09 : 05:55:41
Is it possible to have a variable table name embedded into a SQL string then execute?

I have been at this all morning and have tried searching for the answer without much success.

Whichever option I try I get the error message;

must declare variable @ResultSet.

Here is my string setup;

SELECT @SQLString = '
SELECT
curr_date,
movement_qty,
rolling_balance,
tran_type,
tran_id,
tran_status,
tran_no,
user_nm,
location,
part_no
FROM @ResultSet
WHERE '

I dynamically add the parameters to the where clause then do this;

exec (@SQLString)

Is this another quirky variable issue or am I way off beam?

When I print @SQLString it look as it should do to me?

Thnx

spirit1
Cybernetic Yak Master

11752 Posts

Posted - 2005-06-09 : 06:04:00
SELECT @SQLString = '
SELECT curr_date, movement_qty, rolling_balance, tran_type, tran_id,tran_status,
tran_no, user_nm, location, part_no FROM ' + @ResultSet + ' WHERE '

Go with the flow & have fun! Else fight the flow
Go to Top of Page

hog
Constraint Violating Yak Guru

284 Posts

Posted - 2005-06-09 : 06:10:11
Hi. No I had already tried that and get the same error

The thing is the @ResulSet is the name of the variable table see below.

DECLARE @ResultSet TABLE (id int identity(1,1), curr_date datetime, movement_qty decimal(20,8), rolling_balance decimal(20,8), tran_type varchar(15), tran_id int, tran_status char(1), tran_no int, user_nm varchar(30), location varchar(10), part_no varchar(30), start_date datetime, end_date datetime)
Go to Top of Page

spirit1
Cybernetic Yak Master

11752 Posts

Posted - 2005-06-09 : 06:17:37
ohhh.....

you have to know that variables are limited to a batch.
so doing an exec ('some statement') means that 'some statement' will be exectuted in another batch and won't know about the
table variable.
you have to put it all into a string...

Go with the flow & have fun! Else fight the flow
Go to Top of Page

hog
Constraint Violating Yak Guru

284 Posts

Posted - 2005-06-09 : 06:26:03
Oh I see, very handy thing to know, ta.

but....
quote:
Originally posted by spirit1

ohhh.....

you have to put it all into a string...

Go with the flow & have fun! Else fight the flow



perhaps another bit of a clue...

How do I get @ResultSet into a string so that another batch will know about it? Sorry my brain juices just boiled and now I have brain mush on my shirt and the missus will kill me..

In this case would it be better to use a temp table?
Go to Top of Page

spirit1
Cybernetic Yak Master

11752 Posts

Posted - 2005-06-09 : 06:32:45
well you could use a global ##temp table that has no problems with this.
of course fast changing global temp tables with same names aren't good for multiuser enviroments.
but if it's for maintainance it's ok.

what i meant about all in the string is:

declare @sqlstring varchar(8000)
set @sqlstring =
'
declare @MyTable table(id int, other columns);
insert into ....;
select .... from @MyTable where...;
'

and of course if you have any ' in your @sqlstring you have to double them so dynamic sql can interpret them correctly.

Go with the flow & have fun! Else fight the flow
Go to Top of Page

hog
Constraint Violating Yak Guru

284 Posts

Posted - 2005-06-09 : 06:42:39
OOOOW Kool, I shall give that a go
Go to Top of Page

hog
Constraint Violating Yak Guru

284 Posts

Posted - 2005-06-09 : 10:50:21
In the end I could not get this to work. I understand the it and it would have worked but for the fact I have other variable tables processing data before hand and as such I would end up with a stored proc containing one huge string.

I had to use a temp table here and now all works fine. Would rather have stuck to variable tables but they ya go.

thnx
Go to Top of Page

spirit1
Cybernetic Yak Master

11752 Posts

Posted - 2005-06-09 : 10:54:11
well table variables aren't meant for cross batch use
so don't sweat it.


Go with the flow & have fun! Else fight the flow
Go to Top of Page

hog
Constraint Violating Yak Guru

284 Posts

Posted - 2005-06-09 : 11:11:28
Phew! Still at least I understand the limited to batch issues
Go to Top of Page

Seventhnight
Master Smack Fu Yak Hacker

2878 Posts

Posted - 2005-06-09 : 11:29:10
wait... hold on!

Why do you need to use a table variable in a dynamic sql statement?!?

For example... say you have a result set stored in @resultSet

and you want to filter it on one or more items:


select yadayada
From @resultSet
Where
(param1=@param1 or @param1 is null)
and (param2=@param2 or @param2 is null)
and (param3=@param3 or @param3 is null)


It seems like dynamic sql may be the wrong approach...


Corey

Secret Service Agent: Mr. President, you're urinating on me.
President Lyndon Johnson: I know I am. It's my prerogative.
Go to Top of Page

hog
Constraint Violating Yak Guru

284 Posts

Posted - 2005-06-09 : 18:24:53
corey, the only way I can explain what I have done is to list the entire sp. This does exactly what we want as follows.

User must supply part_no and location otherwise a blank dataset is returned.

User can supply start and end date for a range of transactions

User can supply a start date only for transactions on or after that date

User can supply an end date only for transactions up to that date.

It works a treat....really



SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO

CREATE PROCEDURE dbo.ou_transaction_history_sp @WhereClause varchar(1024)='' AS

SET NOCOUNT ON

SET DATEFORMAT dmy

DECLARE @Item_No varchar(30), @Location varchar(10), @Today varchar(20), @EndDate varchar(20), @SQLString varchar(8000)

DECLARE @PosItem int, @PosStart int, @PosEnd int, @PosLoc int, @Pos smallint, @N smallint

DECLARE @Transactions TABLE (id int identity(1,1), curr_date datetime, tran_id int, tran_type char(1), tran_status char(1), tran_no int, movement_qty decimal(20,8), rolling_balance decimal(20,8), tran_mtrl_cost decimal(20,8), user_nm varchar(30), location varchar(10), part_no varchar(30), start_date datetime, end_date datetime)

CREATE TABLE #ResultSet (id int identity(1,1), curr_date datetime, movement_qty decimal(20,8), rolling_balance decimal(20,8), tran_type varchar(15), tran_id int, tran_status char(1), tran_no int, user_nm varchar(30), location varchar(10), part_no varchar(30), start_date datetime, end_date datetime)

-- get position of parameters passed in where clause

SET @PosItem = PATINDEX ( '%part_no%' , @WhereClause )

SET @PosStart = PATINDEX ( '%start_date%' , @WhereClause )

SET @PosEnd = PATINDEX ( '%end_date%' , @WhereClause )

SET @PosLoc = PATINDEX ( '%location%' , @WhereClause )

-- this stored procedure will only do something if a part number and location are supplied in the where clause

IF @PosItem > 0 AND @PosLoc > 0
BEGIN
-- get the part_no sent by user

SELECT @Pos = @PosItem, @N = 0

WHILE(1=1)
BEGIN
SELECT @Pos = CHARINDEX('%',@WhereClause,@Pos+1), @N = @N + 1

IF @Pos = 0
BREAK

IF @N % 2 = 1
BEGIN
SET @Item_No = SUBSTRING(@WhereClause,@Pos+1,CHARINDEX('%',@WhereClause,@Pos+1)-@Pos-1)
BREAK
END
END

-- get the location sent by user

SELECT @Pos = @PosLoc, @N =0

WHILE(1=1)
BEGIN
SELECT @Pos = CHARINDEX('%',@WhereClause,@Pos+1), @N = @N + 1

IF @Pos = 0
BREAK

IF @N % 2 = 1
BEGIN
SET @Location = SUBSTRING(@WhereClause,@Pos+1,CHARINDEX('%',@WhereClause,@Pos+1)-@Pos-1)
BREAK
END
END

-- load all transactions for supplied part_no and location into @transactions

INSERT @Transactions (curr_date, tran_id, tran_type, tran_status, tran_no, movement_qty, rolling_balance, tran_mtrl_cost, user_nm, location, part_no)
SELECT
curr_date,
tran_id,
tran_type,
tran_status,
tran_no,
tran_inv_qty,
0,
tran_mtrl_cost,
user_nm,
location,
part_no
FROM dbo.inv_tran
WHERE part_no = @Item_No AND location = @Location AND LEN(RTRIM(update_typ))>0
AND tran_type <> 'C' AND tran_type <> 'H'
AND tran_status <> 'P'

-- calculate all transactions rolling balances into @ResultSet table

INSERT #ResultSet (curr_date, movement_qty, rolling_balance, tran_type, tran_id, tran_status, tran_no, user_nm, location, part_no)
SELECT
curr_date,
movement_qty,
rolling_balance = (SELECT SUM(movement_qty) FROM @Transactions where id <= A.id),
tran_type = CASE tran_type WHEN 'I' THEN 'Inv Adj' WHEN 'S' THEN 'Sales' WHEN 'U' THEN 'Usage' WHEN 'P' THEN 'Produce' ELSE 'Unknown' END,
tran_id,
tran_status,
tran_no,
user_nm,
location,
part_no
FROM @Transactions A

-- build SQL to return data to user

SELECT @SQLString = '
SELECT
curr_date,
movement_qty,
rolling_balance,
tran_type,
tran_id,
tran_status,
tran_no,
user_nm,
location,
part_no
FROM #ResultSet
WHERE '

-- get start date if sent by user

IF @PosStart > 0
SELECT @SQLString = @SQLString + 'curr_date >= ''' + SUBSTRING(@WhereClause, @PosStart+20, 8) + ''''

ELSE
SELECT @SQLString = @SQLString + 'curr_date >= ''2000/01/01'''

-- get end date if sent by user

IF @PosEnd > 0
BEGIN

SELECT @EndDate = SUBSTRING(@WhereClause, @PosEnd+18, 8 ) + ' 23:59:59'

SELECT @SQLString = @SQLString + ' AND curr_date <= ''' + @EndDate + ''' ORDER BY curr_date, tran_id'

END

ELSE
BEGIN

SELECT @Today = convert(varchar, GETDATE(), 103) + ' 23:59:59'

SELECT @SQLString = @SQLString + ' AND curr_date <= ''' + @Today + ''' ORDER BY curr_date, tran_id'

END

-- send data back to user

exec (@SQLString)

END
ELSE

-- if part_no or location not supplied return an empty table

SELECT * FROM #ResultSet

GRANT ALL ON dbo.ou_transaction_history_sp TO PUBLIC

Go to Top of Page

Seventhnight
Master Smack Fu Yak Hacker

2878 Posts

Posted - 2005-06-09 : 19:57:15
yeah I don't think you need dynamic SQL, you could utilize the concept i gave and example for a few posts back... but whatever floats your boat.

Corey

Secret Service Agent: Mr. President, you're urinating on me.
President Lyndon Johnson: I know I am. It's my prerogative.
Go to Top of Page

hog
Constraint Violating Yak Guru

284 Posts

Posted - 2005-06-09 : 21:36:03
Hi, I can't see how I can include the date parameters into the where clause as shown without using dynamic sql?
Go to Top of Page

Seventhnight
Master Smack Fu Yak Hacker

2878 Posts

Posted - 2005-06-09 : 23:01:35
i'll expound in the morning...

Corey

Secret Service Agent: Mr. President, you're urinating on me.
President Lyndon Johnson: I know I am. It's my prerogative.
Go to Top of Page
   

- Advertisement -