Create a temporary table in SQL on the fly - sql

How can I create a temporary table without first creating the columns?
CREATE TABLE #Yaks (
YakID int,
YakName char(30) )
select name
from tempdb..sysobjects
where name like '#yak%'
drop table #yaks
It is a pain to have to define the table first.

Create a (temp) table with the same columns as another (no data copied):
select * into #TempTable
from MyTable
where 1=0
Note: Does not create any Foreign keys, indexes etc...

Related

How can I create table not declare column but copy from another?

I want to create a stored procedure to return all column data from a table except one column that key of where condition. The original table will be change a lot during my project, so I don't want to create table with declaring columns. How can I create the table that columns are copy of another table? I'm using SQL Server.
ALTER PROCEDURE [dbo].[SelectCharacterDataById]
#Id INT
AS
BEGIN
SET NOCOUNT ON;
CREATE TABLE #TempTable
AS
SELECT *
FROM dbo.CharacterData
WHERE CharacterID = #Id
ALTER TABLE #TempTable
DROP COLUMN CharacterID
SELECT *
FROM #TempTable
END

Add identity increment property to existing tables at once

I have multiple tables in database all table has id column which is primary key.
I want a script by which i can add identity property to all tables at once rather than I go and change one by one.
You can't alter the existing columns for identity.
You have 2 options:
Create a new table with identity & drop the existing table
Create a new column with identity & drop the existing column
But take spl care when these columns have any constraints / relations.
For already craeted table Names
Drop table Names
Create table Names
(
ID int,
Name varchar(50)
)
Insert Into Names Values(1,'SQL Server')
Insert Into Names Values(2,'ASP.NET')
Insert Into Names Values(4,'C#')
In this Approach you can retain the existing data values on the newly
created identity column
CREATE TABLE dbo.Tmp_Names
(
Id int NOT NULL IDENTITY (1, 1),
Name varchar(50) NULL
) ON [PRIMARY]
go
SET IDENTITY_INSERT dbo.Tmp_Names ON
go
IF EXISTS(SELECT * FROM dbo.Names)
INSERT INTO dbo.Tmp_Names (Id, Name)
SELECT Id, Name FROM dbo.Names TABLOCKX
go
SET IDENTITY_INSERT dbo.Tmp_Names OFF
go
DROP TABLE dbo.Names
go
Exec sp_rename 'Tmp_Names', 'Names'
In this approach you can’t retain the existing data values on the
newly created identity column;
The identity column will hold the sequence of number
Alter Table Names Add Id_new Int Identity(1,1)
Go
Alter Table Names Drop Column ID
Go
Exec sp_rename 'Names.Id_new', 'ID','Column'
Source 1
What you can do is write a quick query to generate the SQL for you
like so:
USE INFORMATION_SCHEMA;
SELECT
CONCAT("ALTER TABLE `", TABLE_SCHEMA,"`.`", TABLE_NAME, "` CONVERT TO CHARACTER SET UTF8;")
AS MySQLCMD FROM TABLES
WHERE TABLE_SCHEMA = "your_schema_goes_here";
Then you can run the output from this to do what you need.
Source 2
EDIT
You could check Altering Multiple Tables at once

Derived table with an index

Please see the TSQL below:
DECLARE #TestTable table (reference int identity,
TestField varchar(10),
primary key (reference))
INSERT INTO #TestTable VALUES ('Ian')
select * from #TestTable as TestTable
INNER JOIN LiveTable on LiveTable.Reference=TestTable.Reference
Is it possible to create an index on #Test.TestField? The following webpage suggests it is not. However, I read on another webpage that it is possible.
I know I could create a physical table instead (for #TestTable). However, I want to see if I can do this with a derived table first.
You can create an index on a table variable as described in the top voted answer on this question:
SQL Server : Creating an index on a table variable
Sample syntax from that post:
DECLARE #TEMPTABLE TABLE (
[ID] [INT] NOT NULL PRIMARY KEY,
[Name] [NVARCHAR] (255) COLLATE DATABASE_DEFAULT NULL,
UNIQUE NONCLUSTERED ([Name], [ID])
)
Alternately, you may want to consider using a temp table, which will persist during the scope of the current operation, i.e. during execution of a stored procedure exactly like table variables. Temp tables will be structured and optimized just like regular tables, but they will be stored in tempDb, therefore they can be indexed in the same way as regular table.
Temp tables will generally offer better performance than table variables, but it's worth testing with your dataset.
More in depth details can be found here:
When should I use a table variable vs temporary table in sql server?
You can see a sample of creating a temp table with an index from:
SQL Server Planet - Create Index on Temp Table
One of the most valuable assets of a temp table (#temp) is the ability
to add either a clustered or non clustered index. Additionally, #temp
tables allow for the auto-generated statistics to be created against
them. This can help the optimizer when determining cardinality. Below
is an example of creating both a clustered and non-clustered index on
a temp table.
Sample code from site:
CREATE TABLE #Users
(
ID INT IDENTITY(1,1),
UserID INT,
UserName VARCHAR(50)
)
INSERT INTO #Users
(
UserID,
UserName
)
SELECT
UserID = u.UserID
,UserName = u.UserName
FROM dbo.Users u
CREATE CLUSTERED INDEX IDX_C_Users_UserID ON #Users(UserID)
CREATE INDEX IDX_Users_UserName ON #Users(UserName)

Convert an existing Column to Identity

I have a table in SQL Server with bundle of records. I want to convert the ID column which is Primary Key to an identity Column without loss of data. I thought of the following two approaches:
Create a new table with identity & drop the existing table.
Create a new column with identity & drop the existing column.
but it's clear that they can not be implemented because keeping records is my first priority.
Is there another way to do this?
This solution violates your point 2, but there is no other way and I think your aim is to keep the old values, because nothing else makes sense...
You could do the following:
make it possible to insert into identity columns in your table:
set identity_insert YourTable ON
add a new ID column to your table with identity and insert the values from your old columns
turn identity insert off
set identity_insert YourTable OFF
delete old ID column
rename new column to old name
make it to the primary key
The only problem could be that you have your ID column already connected as foreign key to other tables. Then you have a problem with deleting the old column...
In this case you have to drop the foreign key constraints on your ID column after step 3, then do step 4 to 6 and then recreate your foreign key constraints.
As you are using SQL Server 2012, another possible alternative could be to create a sequence object that has a starting value of the highest ID +1 already in your table, then create a default constraint for your column using GET NEXT VALUE FOR and reference your sequence object you just created.
If you have direct access to the Server Database, just go into the design of the table, select the PK column, and change the identity to "Yes". Make sure you set your seed to the max value of that column. The increment is 1 by default. Save the table design and you should be good to go.
Considering the source table isn't too big:
Create new table (with IDENTITY)
Populate new table from existing table (with IDENTITY_INSERT ON)
Drop old table (drop any existing FKs first)
Rename new table to old name (re-establish FKs if needed)
-- Create Sample Existing Table
DROP TABLE IF EXISTS #tblTest
CREATE TABLE #tblTest
(
ID INT NOT NULL
, Val VARCHAR(10) NOT NULL
)
INSERT INTO #tblTest
(
ID
, Val
)
VALUES
(1, 'a')
, (2, 'b')
, (4, 'c')
GO
-- Create and Populate New Table (with IDENTITY_INSERT ON)
DROP TABLE IF EXISTS #tblTestNew
CREATE TABLE #tblTestNew
(
ID INT IDENTITY(1, 1) NOT NULL
, Val VARCHAR(10) NOT NULL
)
SET IDENTITY_INSERT #tblTestNew ON
INSERT INTO #tblTestNew
(
ID
, Val
)
(
SELECT
#tblTest.ID
, #tblTest.Val
FROM
#tblTest
)
SET IDENTITY_INSERT #tblTestNew OFF
GO
-- Rename Existing Table to Old (can use sp_rename instead, but I can't for temp tables)
SELECT * INTO #tblTestOld FROM #tblTest
DROP TABLE #tblTest
GO
-- Rename New Table to Existing (can use sp_rename instead, but I can't for temp tables)
SELECT * INTO #tblTest FROM #tblTestNew
DROP TABLE #tblTestNew
GO
-- Test Inserting new record
INSERT INTO #tblTest (Val)
VALUES ('d')
-- Verify Results
SELECT * FROM #tblTest
EXEC tempdb.sys.sp_help #objname = N'#tblTest'
-- Drop 'Old' Table (when ready)
DROP TABLE IF EXISTS #tblTestOld
-- Cleanup
DROP TABLE IF EXISTS #tblTest
DROP TABLE IF EXISTS #tblTestNew
DROP TABLE IF EXISTS #tblTestOld
If the table is very large, consider the log growth, Recovery Model, possible single-user mode, etc.
create table t1 (col1 int, col2 varchar(10))
insert into t1 values (10, 'olddata')
--add identity col
alter table t1 add col3 int identity(1,1)
GO
--rename or remove old column
alter table t1 drop column col1
--rename new col to old col name
exec sp_rename 't1.col3', 'col1', 'column'
GO
--add new test , review table
insert into t1 values ( 'newdata')
select * from t1

Drop a temporary table if it exists

I have two lines of code in SQL that create two tables on the fly, i need to do something like
IF TABLE EXISTS
DROP IT AND CREATE IT AGAIN
ELSE
CREATE IT
my lines are the following ones
CREATE TABLE ##CLIENTS_KEYWORD(client_id int)
CREATE TABLE ##TEMP_CLIENTS_KEYWORD(client_id int)
how can I apply that concept for these two tables in my procedure?
From SQL Server 2016 you can just use
DROP TABLE IF EXISTS ##CLIENTS_KEYWORD
On previous versions you can use
IF OBJECT_ID('tempdb..##CLIENTS_KEYWORD', 'U') IS NOT NULL
/*Then it exists*/
DROP TABLE ##CLIENTS_KEYWORD
CREATE TABLE ##CLIENTS_KEYWORD
(
client_id INT
)
You could also consider truncating the table instead rather than dropping and recreating.
IF OBJECT_ID('tempdb..##CLIENTS_KEYWORD', 'U') IS NOT NULL
TRUNCATE TABLE ##CLIENTS_KEYWORD
ELSE
CREATE TABLE ##CLIENTS_KEYWORD
(
client_id INT
)
Check for the existence by retrieving its object_id:
if object_id('tempdb..##clients_keyword') is not null
drop table ##clients_keyword
What you asked for is:
IF OBJECT_ID('tempdb..##CLIENTS_KEYWORD') IS NOT NULL
BEGIN
DROP TABLE ##CLIENTS_KEYWORD
CREATE TABLE ##CLIENTS_KEYWORD(client_id int)
END
ELSE
CREATE TABLE ##CLIENTS_KEYWORD(client_id int)
IF OBJECT_ID('tempdb..##TEMP_CLIENTS_KEYWORD') IS NOT NULL
BEGIN
DROP TABLE ##TEMP_CLIENTS_KEYWORD
CREATE TABLE ##TEMP_CLIENTS_KEYWORD(client_id int)
END
ELSE
CREATE TABLE ##TEMP_CLIENTS_KEYWORD(client_id int)
Since you're always going to create the table, regardless of whether the table is deleted or not; a slightly optimised solution is:
IF OBJECT_ID('tempdb..##CLIENTS_KEYWORD') IS NOT NULL
DROP TABLE ##CLIENTS_KEYWORD
CREATE TABLE ##CLIENTS_KEYWORD(client_id int)
IF OBJECT_ID('tempdb..##TEMP_CLIENTS_KEYWORD') IS NOT NULL
DROP TABLE ##TEMP_CLIENTS_KEYWORD
CREATE TABLE ##TEMP_CLIENTS_KEYWORD(client_id int)