Reputation: 5266
I need to insert some data into a temp table.
I have some conditional based columns like Salary
, Code
.
How can I create a table for conditional based columns? I don't want to use
SELECT INTO #tempTable
Here is the code:
DECLARE @sql NVARCHAR(MAX)
,@sqlSelect NVARCHAR(MAX) = ''
,@sqlFrom NVARCHAR(MAX) =''
CREATE TABLE #myTempTable (Id INT, DeptId INT, DeptName VARCHAR(100))
SET @sqlSelect ='INSERT INTO #myTempTable
SELECT EMP.Id, EMP.DeptId, EMP.DeptName'
SET @sqlFrom =' FROM dbo.EMPLOYEE AS EMP'
IF (someCondition)
BEGIN
SET @sqlSelect = @sqlSelect +', EMP.Salary, EMP.Code'
END
SET @sql = @sqlSelect +@sqlFrom
EXEC sp_executesql @sql
Any help/suggestion on how better i can make this?
Update:
Initially I used SELECT INTO #TempTable
without specifying no of columns, As SQL Azure not supporting that, I decided to go with INSERT INTO
. But not sure how can I add dynamic columns in a defined structure already. Its fully dynamic SQL :(
Upvotes: 7
Views: 50076
Reputation: 1515
Here is another solution with completely dynamic columns:
DECLARE @sql NVARCHAR(MAX)
,@sqlTableName NVARCHAR(MAX) = ''
,@sqlColumnsDefinitions NVARCHAR(MAX) =''
,@sqlColumnsList NVARCHAR(MAX) =''
,@sqlFrom NVARCHAR(MAX) =''
SET @sqlTableName = 'myTempTable'
SET @sqlFrom = 'FROM dbo.EMPLOYEE AS EMP'
--conditions to define columns
IF (1=1)
set @sqlColumnsDefinitions='Col1 int, Col2 int, Col3 int'
else
set @sqlColumnsDefinitions='Col1 int, Col2 int, Col3 int, Col4 int, Col5 int'
--new table with dynamic fields creation
SET @sql = 'if (object_id('''+@sqlTableName+''') is not null) DROP TABLE '+@sqlTableName+'
CREATE TABLE '+@sqlTableName+' ('+@sqlColumnsDefinitions+')'+char(10)
print (@sql)
exec (@sql)
--get columns list
select @sqlColumnsList=STUFF((SELECT ',' + column_name
from INFORMATION_SCHEMA.COLUMNS where table_name like @sqlTableName+'%' FOR XML PATH('')), 1, 1, '')
--main insert
SET @sql = 'INSERT INTO '+@sqlTableName+char(10)+'SELECT '+@sqlColumnsList+char(10)+@sqlFrom
print (@sql)
exec (@sql)
This won't work if you substite myTempTable with #myTempTable because of SQL engine. To fix it and get correct column names list you may use some tricks that are out of scope. But still it works with non-temp tables.
Upvotes: 0
Reputation: 41
Try This.
Begin Tran IF (someCondition) Begin CREATE TABLE #myTempTable (Id INT, DeptId INT, DeptName VARCHAR(100), Salary money , Code Int) Insert Into #myTempTable(Id, DeptId, DeptName, Salary, Code) Select Emp.Id, Emp.DeptID, Emp.DeptName, EMP.Salary, EMP.Code From dbo.Employee As Emp Select Id, DeptID, DeptName, Salary, Code From dbo.Employee Drop Table #myTempTable End Else Begin CREATE TABLE #myTempTable2 (Id INT, DeptId INT, DeptName VARCHAR(100)) Insert Into #myTempTable(Id, DeptId, DeptName) Select Emp.Id, Emp.DeptID, Emp.DeptName From dbo.Employee As Emp Select Id, DeptID, DeptName From dbo.Employee Drop Table #myTempTable2 End Commit Tran
Upvotes: 0
Reputation: 1648
If this table is BIG I think your and in your logic you make JOINS with this table you need to create indexes in TARGET TABLE
You can go around with Physical table not TEMP
DECLARE @guid NVARCHAR(64), @sql NVARCHAR(MAX)
,@sqlSelect NVARCHAR(MAX) = ''
,@sqlFrom NVARCHAR(MAX) ='', @sqlSchema NVARCHAR(MAX) =''
SET @guid = NEWID()
declare @tableName NVARCHAR(64)= 'myTempTable'+ @guid
select @tableName
--use some transaction
set @sql = 'CREATE TABLE ' + @tableName
set @sqlSchema = '(Id INT, DeptId INT, DeptName VARCHAR(100)' -- DO INDEXES IF YOU ARE JOIN
SET @sqlSelect ='INSERT INTO ' + @tableName +
'SELECT EMP.Id, EMP.DeptId, EMP.DeptName'
IF (1=1) -- your condition
BEGIN
SET @sqlSchema = @sqlSchema +', EMP.Salary, EMP.Code'
END
SET @sqlSchema = @sqlSchema + ')' -- close last )
set @sql = @sql +@sqlSchema --create the TargetTable
--DO YOUR logic
EXEC sp_executesql @sql
set @sql = N'DROP TABLE ' + @tableName
EXEC sp_executesql @sql
Upvotes: 0
Reputation: 1220
use the code and tell me is it working or not ??
-----------------------------------------------------
DECLARE @sql NVARCHAR(MAX)
,@sqlSelect NVARCHAR(MAX) = ''
,@sqlFrom NVARCHAR(MAX) =''
IF (someCondition)
BEGIN
CREATE TABLE #tblInfo (Id INT, DeptId INT, DeptName VARCHAR(100))
END
ELSE
BEGIN
CREATE TABLE #tblInfo (Id INT, DeptId INT, DeptName VARCHAR(100),Salary numeric(18,2), Code INT)
END
SET @sqlSelect ='INSERT INTO #tblInfo
SELECT EMP.Id, EMP.DeptId, EMP.DeptName'
SET @sqlFrom =' FROM dbo.EMPLOYEE AS EMP'
IF (someCondition)
BEGIN
SET @sqlSelect = @sqlSelect +', EMP.Salary, EMP.Code'
END
SET @sql = @sqlSelect +@sqlFrom
EXEC sp_executesql @sql
------------------------------------
I hope it will work
Upvotes: 0
Reputation: 116
As alluded to, your best bet is to likely create all of the columns that you will need and make them NULLable if optional. So:
CREATE TABLE #myTempTable (Id INT, DeptId INT, DeptName VARCHAR(100), Salary INT NULL, EmpCode VARCHAR(45) NULL);
And
IF (someCondition)
BEGIN
SET @sqlSelect = @sqlSelect +', EMP.Salary, EMP.Code'
END
ELSE
BEGIN
SET @sqlSelect = @sqlSelect +', NULL, NULL'
END
Upvotes: 1
Reputation: 197
I think what you really are looking for is impossible for SQL. As I undrestand you want to add column for, for example tuples that met the conditions. So I think you need some other database engines like NoSQL(I'm not very familiar with NoSQL but as much as I know it can horizontally scale)
If you don't want to switch from sql I think you should reconsider your design.
If you insist on your design you can do things like for example add a column, name "column name" and another column "column data" and fill it when its needed. But as you can see it has its own constraints like the data of "column data" should be the same type.
Upvotes: 0
Reputation: 127
Can you use the
sp_RENAME 'TableName.[OldColumnName]' , '[NewColumnName]', 'COLUMN'
command to change the name of a previously defined place holder column.
For example, create the #tempTable
with extra fields such as "VCHAR100_1"
, "BOOL_1"
, "Int_1"
, etc. If you need to use the field, rename it to the desired name so your code later on can refer to the column by a non-cryptic name.
Upvotes: 0
Reputation: 103
You could just alter the temp table when the condition is met (I'm assuming you know the columns required at this point?)
IF (someCondition)
BEGIN
ALTER TABLE #myTempTable ADD Salary VARCHAR(20), Code VARCHAR(20)
SET @sqlSelect = @sqlSelect +', EMP.Salary, EMP.Code'
END
You may want to test if the column exists first, if you have more than one condition that could be activated - which you can do like so:
IF COL_LENGTH('#myTemptable','Salary') IS NULL
BEGIN
-- do something if salary doesn't exist
ALTER TABLE #myTempTable ADD Salary NUMERIC(6,2)
END
As others have noted, you could create the columns upfront as nullable - or create the table after the condition is met.
Upvotes: 0
Reputation: 21
Below code may work for you.
DECLARE @sql NVARCHAR(MAX)
,@sqlSelect NVARCHAR(MAX) = ''
,@sqlFrom NVARCHAR(MAX) =''
IF (someCondition)
BEGIN
CREATE TABLE #myTempTable (Id INT, DeptId INT, DeptName VARCHAR(100))
END
ELSE
BEGIN
CREATE TABLE #myTempTable (Id INT, DeptId INT, DeptName VARCHAR(100),Salary numeric(18,2), Code INT)
END
SET @sqlSelect ='INSERT INTO #myTempTable
SELECT EMP.Id, EMP.DeptId, EMP.DeptName'
SET @sqlFrom =' FROM dbo.EMPLOYEE AS EMP'
IF (someCondition)
BEGIN
SET @sqlSelect = @sqlSelect +', EMP.Salary, EMP.Code'
END
SET @sql = @sqlSelect +@sqlFrom
EXEC sp_executesql @sql
Upvotes: 0
Reputation: 156
See example below:
declare @sql nvarchar(400)
declare @ColFlag int
set @ColFlag = 1
if(@ColFlag = 0)
set @sql= 'CREATE TABLE #myTempTable (Id INT, DeptId INT, DeptName VARCHAR(100));
INSERT INTO #myTempTable SELECT 1,2,''DeptName1'';
SELECT * FROM #myTempTable'
else
set @sql= 'CREATE TABLE #myTempTable (Id INT, DeptId INT, DeptName VARCHAR(100), MyNewColHere VARCHAR(25));
INSERT INTO #myTempTable SELECT 1,2,''DeptName1'', ''MyNewColHereValue'';
SELECT * FROM #myTempTable'
exec (@sql)
Upvotes: 0
Reputation: 9583
How many dynamic columns do you need?
What about having a column called Dynamic
of type nvarchar(MAX)
or something of the like, and then you can just put your data in there and format as appropriate.
Another option is to create a table with NULL
columns.
To do this in SQL, you can do the following:
CREATE TABLE tblPerson
(
PersonId INT,
FirstName NVARCHAR(256),
LastName NVARCHAR(256) NULL,
PRIMARY KEY (PersonId)
)
Notice the NULL
column above also.
See here for further explanation on creating tables with Primary Keys
and NULL
columns in SQL:
Upvotes: 1