Cannot rename the column of a temp table - sql

I created a global temp table like this -
CREATE TABLE ##BigTable
(Nos varchar(10) null)
Then try to rename the Nos column like this -
EXEC sp_RENAME '##BigTable.Nos' , 'Numbers', 'COLUMN'
I got the error -
Either the parameter #objname is ambiguous or the
claimed #objtype (COLUMN) is wrong.
Why could this be happening and how do I solve the problem ?
EXTRA stuff not exactly related to the question, but for reference.
I want to add this - I tried to create the global temp table using a fully qualified
name like this -
CREATE TABLE [NotMyTempDataBase].[dbo].[##BigTable]
(Nos varchar(10) null)
Then, I tried to rename it using -
EXEC tempdb.sys.sp_rename N'[NotMyTempDataBase].[dbo].[##BigTable].Nos',
N'Numbers', N'COLUMN';
Error - The qualified #oldname references a database other than the current database.
This is wrong. I realized that the temp table is created in the system database tempdb, even though you specify another DB name while creating it.
use this instead -
CREATE TABLE [tempdb].[dbo].[##BigTable]
(Nos varchar(10) null)
--SQL server message : Database name 'tempdb' ignored, referencing object in tempdb.
EXEC tempdb.sys.sp_rename N'[tempdb].[dbo].[##BigTable].Nos',
N'Numbers', N'COLUMN';

Ok, so the actual solution is:
EXEC tempdb.sys.sp_rename N'##BigTable.Nos', N'Numbers', N'COLUMN';
Since the #temp table (even a ##global temp table) lives in tempdb, you need to invoke sp_rename there.
But further questions to consider:
Why on earth are you using a ##global temp table? You know this effectively limits concurrency to ONE, right? What do you think will happen when two users call this code at the same time? Probably you want to use a #local temp table here, or maybe avoid #temp tables altogether.
Why do you have the need to change the column name halfway through the script? Either name it right in the first place, or keep referencing the old name. How is the script later on going to know you changed the name? For what purpose?

Also , This worked for me. It may helpful to someone
EXEC tempdb.sys.sp_rename N'#Tab1.Info', N'Numbers', N'COLUMN';

Related

For how long does a temporary table "live" in dynamic SQL code in Msn SSMS?

I have a problem with temporary tables that does not "live" long enough in my code.
My problem looks like this: I want to create a temporary table in one "codevariable" and use it later. An example of my code structure is like below:
declare #RW varchar(MAX)
set #RW = '
select *
into #temptable
from table1'
exec(#RW)
--Alots of other code.
select *
from #temptable
This results in an error message that sais "Invalid object name '#temptable'. And it's very clear that my temporary table does'nt exists anymore. But I've checked that the table creates in the first step. For example the following code works:
declare #RW varchar(MAX)
set #RW = '
select *
into #temptable
from table1
select *
from #temptable'
exec(#RW)
So my GUESS is that the temporary table only lives within it's code variable. Is there a way to create a temporary table that lives longer? Or, do I just needs to accept this for what it is or am I missing something? I have a work around solution that is not very efficient. What I'm thinking of is creating a regular table which I later delete. This would mean a lot of writing to disks but it's something that the system I work with would survive, but not be happy with. Is there any other way to handle this?
A temporary table only persists for the duration of the scope that declared it. For a "normal" connection that will be when the connection is dropped. For example, if you're using SSMS and open a query window and run CREATE TABLE #T (ID int); it'll create the table. As you're still connected, the table won't be dropped and will still exist. If you run the statement again (without dropping it) you'll get an error that it already exists. As soon as you close that query window, the temporary table will be dropped.
For a dynamic statement, the scope is the duration of that dynamic statement. This means that as soon as the dynamic statement completes, the table will be dropped:
EXEC sys.sp_executesql N'CREATE TABLE #T (ID int);';
SELECT *
FROM #t;
Notice this errors, as the scope the table was created in has completed, and thus dropped.
If you are using dynamic statements to create temporary tables, you need to make all the references to said temporary table within the dynamic statement.
Otherwise, if you need to reference it outside of the statement, I personally find I create an "permanent" object in tempdb, and then clean up afterwards.
EXEC sys.sp_executesql N'CREATE TABLE tempdb.dbo.T (ID int);';
SELECT *
FROM tempdb.dbo.T;
DROP TABLE tempdb.dbo.T;
These tables are still dropped in the event the instance is restarted as well.
Note that "global" temporary table behave slightly differently. As global temporary table can be referenced in any connection, while it exists. This means that another connection could be using the table while the scope that created it ends. As a result a global temporary table persists until the scope that declared is ends and there are no other active connections using the object. This means that the objects could be dropped mid batch in another connection.

Renaming index gives error Explicit #objtype id not recognised

I am trying to rename an index and getting an error:
Error: Explicit #objtype 'idx_FinData20' is unrecognized.
I can see both the table and index exist. Then what is the problem
IF ( EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbo' AND TABLE_NAME ='FinData2000_1_old'))
BEGIN
EXEC sp_rename 'FinData2000_1_old.idx_FinData2000_1' , 'idx_FinData2000_1', 'idx_FinData20 00_1_old'
end
First - your syntax is wrong. You need only two arguments, first should be table_name.old_name and second one is just new name.
Second - you have an extra space in your new index name which breaks the script.
EXEC sp_rename 'FinData2000_1_old.idx_FinData2000_1' , 'idx_FinData2000_1_old'
Your were using the wrong syntax for SP_RENAME, by default, it accepts two inputs, the 1st one is old name, the 2nd one is new name, if you would specify the 3rd one(optional and for diffing the objects), that should be the object name.
I am not sure what is the correct case for you, but as an example, you can try this:
EXEC SP_RENAME 'INDEX_OLD_NAME', 'INDEX_NEW_NAME', 'INDEX'
As an additional notes: doing the rename will have potential risk of breaking the remaining process.
learn.microsoft.com specifies that #ObjType can only have one of the following values.
Column
Database
Index
Object
Statistics (SQL Server 2012 (11.x) and later and Azure SQL Database.)
UserDataType
There are internal processes for renaming tables and views that handle the table and view references for #ObjType automatically. So if you're renaming tables/views, leave off #ObjType since the engine is smart enough to figure it out on its own.
Also make sure to include the schema (even if its just dbo so it becomes second nature to you to include it in the future...) in #ObjName since there may be the same named tables in different schemas.
It is also worthy to note that once you rename a table, any indexes you made on the old table are automatically updated to reference the new table name that you just updated it to.
I've finally worked out that some objects need to be quoted. This can be done with the QUOTENAME() function.
For example, I have a primary key constraint created by EF6 named PK_dbo.SafetyDataSheets.
To rename this constraint name the following can be used:
EXEC sp_rename 'dbo.' + QUOTENAME(`PK_dbo.SafetyDataSheets`), 'PK_SafetyDataSheets'

Stored procedure temporary table causing timeout error

I have a temporary table in the stored procedure which is causing the time out for the query as it is doing a complex calculation. I want to drop it after it is used. It was created like
DECLARE #SecondTable TABLE
Now I cannot drop it using
drop #SecondTable
in fact I have to use
drop #SecondTable
Does somebody know why?
I'm by no means a SQL guru, but why is the drop even necessary?
If it's a table variable, it will no longer exist once the stored proc exits.
I'm actually surprised that DROP #SecondTable doesn't error out on you; since you're dropping a temporary table there; not a table variable.
EDIT
So based on your comment, my updates are below:
1.) If you're using a table variable (#SecondTable); then no drop is necessary. SQL Server will take care of this for you.
2.) It sounds like your timeout is caused by the calculations using the table, not the dropping of the table itself. In this case; I'd probably recommend using a temporary table instead of a table variable; since a temporary table will let you add indexes and such to improve performance; while a table variable will not. If this still isn't sufficient; you might need to increase the timeout duration on the query.
3.) In SQL; a table variable (#SecondTable) and temporary table (#SecondTable) are two completely different things. I'd refer to the MSDN documentation for Table Variables and Temporary Tables

Check if table variable Exists?

Ive searched StackOverFlow , and didnt find any.
Is there any way for me to know if a Table Variable already exists ?
something like :
IF OBJECT_ID('tempdb..#tbl') IS NOT NULL
DROP TABLE #tbl
but for table Var...
Table variables, because they are variables, are distinct from either temporary or non-temporary tables in that they are not created – they are declared. They are much closer in that respect to ‘normal’ variables rather than to tables.
So, there's as much sense in talking about a table variable's existence as in talking about the existence of any variable: if you have declared the thing in your source code, it exists starting from that point until the end of its scope, which, in SQL Server, is known to be either the batch or the stored procedure/function it is declared in. And if you haven't declared the variable and are trying to reference it in your code, your code will just not compile, rendering any existence check pointless, if ever possible.
Perhaps, if you feel the need to drop and re-(create/declare) a table variable in your script, then you should probably consider using a temporary table instead.
Table variables #table are little bit different from temporary tables #table.
Table variables #table need to declare while temporary tables #table should create.
So as per definition declare variables exist between their defined scope (Begin and End) statement. So no need to drop table variables.
But you can use delete #table statement if you want to delete/drop a table variable.
I know this is an old thread, but hopefully this might help someone who lands here. When developing from SSMS, you may want to re-run a statement that selects into a table variable (eg. select * into #tblvarFoo from dbName.schema.Foo). But, the second time you run it, you get an error that it already exists. So, you decide to drop it first. But then, you have the problem the OP had:
Before I drop a table I should check if it exists, otherwise I will
get an exception...
You don't have to drop the table variable or check for its existence.
Just reconnect (right click in the query window and select "Connection->Change Connection...") to same Server/db as before.

There is already an object named '##Temp' in the database

I have a stored procedure on SQL Server 2000. It contains:
select ... into ##Temp ...
...
drop table ##Temp
When I run the stored procedure with ADO a second time, it prompts:
There is already an object named '##Temp' in the database.
Could anyone kindly tell me what's wrong?
You should re-write your stored proc to drop the temp table if it exists, then you won't ever have this issue
IF (SELECT object_id('TempDB..##Temp')) IS NOT NULL
BEGIN
DROP TABLE ##Temp
END
You are using a global temp table as indicated by the ## at the beginning of the table name. This means multiple sessions can access the table.
It's likely that you have a connection open that created the table, but failed to drop it. Are you sure that the first ADO run actually drop the table. Could it have failed, or did the flow control in the procedure skip the drop statement?
You may want to test the procedure in SQL Server Enterprise Manager to see if it reports any errors.
Since you chose to use a global temporary table ##Temp, it is visible to all SQL connections at any given time. Obviously, while the stored proc is running for one connection, a second connection comes in and tries to create yet another ##Temp but that already exists....
Use connection-local #Temp tables (only one #) instead.
Oh, it's all my fault. I called the SP twice through one connection by mistake.
That's why it always reports error when being called the second time.
Of course you won't know that by reading my description. Sorry guys...
For me this solution works :
IF (SELECT object_id ='#Temp') IS NOT NULL
BEGIN
DROP TABLE #Temp
END