Showing posts with label object_id. Show all posts
Showing posts with label object_id. Show all posts

Friday, February 24, 2012

Global Temp tables

Hi group,

I want to create several global temp tables. I've created a script:

if not object_id('tempdb..##tbl_ProductTypes') is null
begin
drop table ##tbl_ProductTypes
end
select * into ##tbl_ProductTypes from dbo.tbl_ProductTypes

This script creates a global temp table. When I run it in QA the table is created. When I close QA the table is dropped. This is correct since I found the following in BoL:
[Global temporary tables are automatically dropped when the session that created the table ends and all other tasks have stopped referencing them. The association between a task and a table is maintained only for the life of a single Transact-SQL statement. This means that a global temporary table is dropped at the completion of the last Transact-SQL statement that was actively referencing the table when the creating session ended.]

I created a job that executes the statement above. The job exists with success, however the table is not created!

Why wasn't the table created?

TIA

Regards,

SDerix
Hi,

after finishing the job why should SQL Server keep the global temp table in life ? It is automatically dropped as the job ends.

HTH, jens Suessmeyer.

http://www.sqlserver2005.de

|||

The job will run, create the table, and then when the job finishes the table will be dropped unless you have some other connection reading from it immediately. Or am I confused by what you are asking.

What you are trying to do is likely best served by creating a permanent table in tempdb.

if not object_id('tempdb..tbl_ProductTypes') is null
begin
drop table tempdb..tbl_ProductTypes
end
select * into tempdb..tbl_ProductTypes from dbo.tbl_ProductTypes

Now you just run this, and it will exist. If you can clean up afterwards that would be a good thing, as it will waste tempdb space. But if it is minimal it wouldn't be a big deal (just add more space to tempdb, it is more or less just a database, as long as it has plenty of space and is on optimal storage :)

|||Thnx, I was affraid of that!

I really need these 'in memory' tables. When I use 'normal' tables my performance drops from seconds to minutes! Side note: I use several temp tables...

Louis,
I'll give it a go and see what the results are.

global temp table issue with SQL Server 2000

In a SP I create a global temp table as follows:
if not object_id('tempdb..##t') is null drop table ##t
create table ##t (a int, b int)
Then, only on occasion, I get an "invalid column" error when referring to
column b. I think this is due to the fact that I create a table with the sam
e
name -- one that doesn't have column b -- prior to running this SP. However,
this doesn't make any sense since I drop it and create it again...
What I am missing here?Why are you using a global temp table?
Have you ever printed the result of object_id('tempdb..##tt')?
A
"Ken Abe" <KenAbe@.discussions.microsoft.com> wrote in message
news:22351B35-23E4-4C75-954B-4502791E5E4C@.microsoft.com...
> In a SP I create a global temp table as follows:
> if not object_id('tempdb..##t') is null drop table ##t
> create table ##t (a int, b int)
> Then, only on occasion, I get an "invalid column" error when referring to
> column b. I think this is due to the fact that I create a table with the
> same
> name -- one that doesn't have column b -- prior to running this SP.
> However,
> this doesn't make any sense since I drop it and create it again...
> What I am missing here?
>|||Thank you for your reply.
The global temp table is used to interface with another SP. It's global
because this other SP is called in different contexts, including the SP at
hand and a manual query analyser sessions.
I have never printed the return value of the existence test. But here's my
thinking: if the code fails to drop the table for any reason, why doesn't th
e
'create table' statement generate an error?
"Aaron Bertrand [SQL Server MVP]" wrote:

> Why are you using a global temp table?
> Have you ever printed the result of object_id('tempdb..##tt')?
> A
>
> "Ken Abe" <KenAbe@.discussions.microsoft.com> wrote in message
> news:22351B35-23E4-4C75-954B-4502791E5E4C@.microsoft.com...
>
>|||> The global temp table is used to interface with another SP.
http://www.sommarskog.se/share_data.html|||These are very useful tips in general, but they do not explain my problem in
particular. I looked at the comments regarding the use of temp tables for
parameter passing and the related maintenance drawbacks, but mine is a
different situation. I did not modify any parameters. This article (please
correct if I'm wrong) says that errors will occur when the column definition
changes in either the caller or the callee. And that is perfectly normal
behavior. However, my error does not occur in the callee. This is what I do
in the caller:
drop table ##t
create table ##t (a int, b int)
-- fill ##t with input parameters
exec p -- SP 'p' fills column a in ##t, but it does not use column b
select b from ##t -- this is where the error occurs => 'b is an invalid
column'
"Aaron Bertrand [SQL Server MVP]" wrote:

> http://www.sommarskog.se/share_data.html
>
>|||Without exact code where we can reproduce the problem, it is tough to
speculate what happens "only on occasion." Is it even remotely possible
that you are reusing the name #tt in more than one place, for tables with
different structures? You may consider using a more useful, legible and
unique name. I would have absolutely no concept of what would reside in a
table called #tt and would find myself doing a grep for that name in other
people's code, if it were even close to an attractive name to use in my
own...
"Ken Abe" <KenAbe@.discussions.microsoft.com> wrote in message
news:6E47FE3B-5525-445D-BB12-05301672B231@.microsoft.com...
> These are very useful tips in general, but they do not explain my problem
> in
> particular. I looked at the comments regarding the use of temp tables for
> parameter passing and the related maintenance drawbacks, but mine is a
> different situation. I did not modify any parameters. This article (please
> correct if I'm wrong) says that errors will occur when the column
> definition
> changes in either the caller or the callee. And that is perfectly normal
> behavior. However, my error does not occur in the callee. This is what I
> do
> in the caller:
> drop table ##t
> create table ##t (a int, b int)
> -- fill ##t with input parameters
> exec p -- SP 'p' fills column a in ##t, but it does not use column b
> select b from ##t -- this is where the error occurs => 'b is an invalid
> column'
>
> "Aaron Bertrand [SQL Server MVP]" wrote:
>|||You are absolutely right about naming and '##t' is not the real name of this
table. I just used it to explain my point here.
The callee SP p expects temp table ##t with column 'a'. This SP is called by
caller 1 and caller 2.
Caller 1 does:
drop table ##t
create table ##t (a int, b int)
-- populate ##t
exec p
Caller 2 does:
drop table ##t
create table ##t (a int, c char)
-- populate ##t
exec p
select c from ##t -- this is where the error occurs (column c not recognized
)
I never use caller 1 and caller 2 concurrently.
"Aaron Bertrand [SQL Server MVP]" wrote:

> Without exact code where we can reproduce the problem, it is tough to
> speculate what happens "only on occasion." Is it even remotely possible
> that you are reusing the name #tt in more than one place, for tables with
> different structures? You may consider using a more useful, legible and
> unique name. I would have absolutely no concept of what would reside in a
> table called #tt and would find myself doing a grep for that name in other
> people's code, if it were even close to an attractive name to use in my
> own...
>
>
>
> "Ken Abe" <KenAbe@.discussions.microsoft.com> wrote in message
> news:6E47FE3B-5525-445D-BB12-05301672B231@.microsoft.com...
>
>|||Here is the code that will allow reproduction of this error. I take back the
"only on occasion", since you can actually reproduce this behavior all the
time. Create the three SPs below, and then call them one after the other.
-- callee
create procedure [dbo].[callee] as
insert ##t (a)
select 1
-- caller 1
create procedure [dbo].[caller1] as
if not object_id('tempdb..##t') is null drop table ##t
create table ##t (a int, b int)
exec dbo.callee
update ##t set b = 1
-- caller 2
create procedure [dbo].[caller2] as
if not object_id('tempdb..##t') is null drop table ##t
create table ##t (a int, c char)
exec dbo.callee
update ##t set c = 'x'
-- test
exec dbo.caller1
exec dbo.caller2 -- blows up here
/* The code in caller2 that drops the table and creates it again never
executes. In fact, the error happens before any code in caller 2 runs at all
.
It seems as caller 2 does some checking prior to executing, which includes
matching column names to the columns in the tables, if those tables exist. I
f
a table doesn't exist (i.e. you drop ##t before running caller 2), it checks
without errors. */
"Aaron Bertrand [SQL Server MVP]" wrote:

> Without exact code where we can reproduce the problem, it is tough to
> speculate what happens "only on occasion." Is it even remotely possible
> that you are reusing the name #tt in more than one place, for tables with
> different structures? You may consider using a more useful, legible and
> unique name. I would have absolutely no concept of what would reside in a
> table called #tt and would find myself doing a grep for that name in other
> people's code, if it were even close to an attractive name to use in my
> own...
>
>
>
> "Ken Abe" <KenAbe@.discussions.microsoft.com> wrote in message
> news:6E47FE3B-5525-445D-BB12-05301672B231@.microsoft.com...
>
>|||And this is exactly what I was suggesting. You have two different stored
procedures, creating a global temp table with the same name, with different
structure.
STOP DOING THAT. Problem solved.
"Ken Abe" <KenAbe@.discussions.microsoft.com> wrote in message
news:E5DBA890-F8EB-4011-9E7F-7C09015AC4B7@.microsoft.com...
> Here is the code that will allow reproduction of this error. I take back
> the
> "only on occasion", since you can actually reproduce this behavior all the
> time. Create the three SPs below, and then call them one after the other.
> -- callee
> create procedure [dbo].[callee] as
> insert ##t (a)
> select 1
> -- caller 1
> create procedure [dbo].[caller1] as
> if not object_id('tempdb..##t') is null drop table ##t
> create table ##t (a int, b int)
> exec dbo.callee
> update ##t set b = 1
> -- caller 2
> create procedure [dbo].[caller2] as
> if not object_id('tempdb..##t') is null drop table ##t
> create table ##t (a int, c char)
> exec dbo.callee
> update ##t set c = 'x'
> -- test
> exec dbo.caller1
> exec dbo.caller2 -- blows up here
>
> /* The code in caller2 that drops the table and creates it again never
> executes. In fact, the error happens before any code in caller 2 runs at
> all.
> It seems as caller 2 does some checking prior to executing, which includes
> matching column names to the columns in the tables, if those tables exist.
> If
> a table doesn't exist (i.e. you drop ##t before running caller 2), it
> checks
> without errors. */|||On Wed, 21 Dec 2005 08:28:02 -0800, Ken Abe wrote:

>Here is the code that will allow reproduction of this error. I take back th
e
>"only on occasion", since you can actually reproduce this behavior all the
>time. Create the three SPs below, and then call them one after the other.
(snip)
Hi Ken,
This has to do with how the compilation process works. The complete
batch is compiled at once, and SQL Server does not attempt to parse
CREATE TABLE, ALTER TABLE and DROP TABLE statements. If a table does not
exist at compile-time, checking the columns is delayed until execution
time (or rather: until the re-compilation that will occur after creating
the table). If the table does exist, the current definition is used to
check the code and create a plan.
The solution is to drop the table when you're done with it, not retain
it and only drop it right before you want to create a new version. This
way, the table won't exist when the stored procedure is called and there
won't be any compilation time errors.
Best, Hugo
--
(Remove _NO_ and _SPAM_ to get my e-mail address)