7

Мне нужно вставить некоторые данные в временную таблицу.CREATE TABLE с динамической колонкой

У меня есть некоторые условные столбцы, основанные как Salary, Code.

Как создать таблицу для условных столбцов? Я не хочу использовать SELECT INTO #tempTable

Вот код:

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 [email protected] 

EXEC sp_executesql @sql 

Любая помощь/предложение о том, как лучше я могу это сделать?


Update:

Первоначально я использовал SELECT INTO #TempTable без указания нет столбцов, Как SQL Azure не поддерживает, я решил пойти с INSERT INTO. Но не знаю, как я могу добавить динамические столбцы в определенной структуре. Его полностью динамический SQL :(

+0

@MahmoudGamal, Обновлен мой вопрос. См. Раздел обновления для получения дополнительной информации. – Billa

+0

Динамические таблицы столбцов нельзя добавлять динамически. Вам нужно, чтобы все столбцы были определены заранее. – dasblinkenlight

+0

@dasblinkenlight, поэтому мне нужно СОЗДАТЬ таблицу, включая Зарплаты, столбцы кода, даже если они не выбраны? Если это так, то какой порядок он будет вставлять, если я выберу только 3 столбца? Извините, я не очень хорош в sql. – Billa

ответ

1

Сколько динамического столбцов вам нужно?

Что о том, столбец с именем Dynamic типа nvarchar(MAX) или что-то подобное, а затем вы можете просто поставить свои данные там и формат . в зависимости от обстоятельств

Другой вариант заключается в создании таблицы с NULL столбцов

чтобы сделать это в SQL, вы можете сделать следующее:.

CREATE TABLE tblPerson 
(
    PersonId INT, 
    FirstName NVARCHAR(256), 
    LastName NVARCHAR(256) NULL, 
    PRIMARY KEY (PersonId) 
) 

Обратите внимание на колонку NULL выше.

Смотрите здесь для дальнейшего объяснения по созданию таблиц с Primary Keys и NULL столбцов в SQL:

Create tables in SQL

+0

Они вокруг 10+ столбцов. – Billa

+0

Как вы упомянули, вам нужны они динамически, вам нужны все они одновременно? – rhughes

+0

Предположим, у меня есть столбцы по умолчанию 5, и я возьму 2 или более столбца, которые будут добавлены в один или несколько операторов If, которые удовлетворяют некоторому условию – Billa

0

Смотрите пример ниже:

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) 
0

Ниже кода может работать для вас.

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 [email protected] 

EXEC sp_executesql @sql 
+0

Благодарим вас за этот фрагмент кода, который может предоставить некоторую ограниченную краткосрочную помощь. Правильное объяснение [значительно улучшило бы] (// meta.stackexchange.com/q/114762) его долгосрочную ценность, показав * почему * это хорошее решение проблемы и сделало бы его более полезным для будущих читателей с другие, похожие вопросы. Пожалуйста, отредактируйте свой ответ, чтобы добавить какое-то объяснение, включая сделанные вами предположения. –

0

Вы можете просто изменить временную таблицу при выполнении условия (я предполагаю, что вы знаете, столбцы, необходимые в данный момент?)

IF (someCondition) 
BEGIN 
    ALTER TABLE #myTempTable ADD Salary VARCHAR(20), Code VARCHAR(20) 
    SET @sqlSelect = @sqlSelect +', EMP.Salary, EMP.Code'    
END 

Вы можете проверить, если столбец существует первых, если у вас есть более чем одно условие, которое может быть активирован - что вы можете сделать, как так:

IF COL_LENGTH('#myTemptable','Salary') IS NULL 
BEGIN 
    -- do something if salary doesn't exist 
    ALTER TABLE #myTempTable ADD Salary NUMERIC(6,2) 
END 

Как уже отмечалось, можно создать столбцы авансовые как Nullable - или создать таблицу после conditi on выполняется.

0

Вы можете использовать команду

sp_RENAME 'TableName.[OldColumnName]' , '[NewColumnName]', 'COLUMN' 

изменить имя ранее определенного столбца держателя место.
Например, создайте #tempTable с дополнительными полями, такими как "VCHAR100_1", "BOOL_1", "Int_1" и т. Д. Если вам нужно использовать это поле, переименуйте его в нужное имя, чтобы ваш код позже мог ссылаться на столбец несимптомным имя.

0

Я думаю, что то, что вы действительно ищете, невозможно для SQL. Поскольку я undrestand вы хотите добавить столбец, например, кортежи, которые удовлетворяли условиям. Поэтому я думаю, что вам нужны другие двигатели базы данных, такие как NoSQL (я не очень хорошо знаком с NoSQL, но насколько я знаю, он может масштабироваться по горизонтали)

Если вы не хотите переключаться с sql, я думаю, вы должны пересмотреть свои дизайн.
Если вы настаиваете на своем дизайне, вы можете делать такие вещи, как, например, добавить столбец, имя «имя столбца» и другой столбец «данные столбца» и заполнить его, когда это необходимо. Но, как вы видите, у него есть свои собственные ограничения, такие как данные «данных столбца» должны быть одного типа.

1

Как указано, лучше всего создать все столбцы, которые вам понадобятся, и сделать их NULLable, если это необходимо. Итак:

CREATE TABLE #myTempTable (Id INT, DeptId INT, DeptName VARCHAR(100), Salary INT NULL, EmpCode VARCHAR(45) NULL); 

И

IF (someCondition) 
BEGIN 
    SET @sqlSelect = @sqlSelect +', EMP.Salary, EMP.Code'    
END 
ELSE 
BEGIN 
    SET @sqlSelect = @sqlSelect +', NULL, NULL'    
END 
0

использовать код и скажите мне, это работает или нет ??

----------------------------------------------------- 

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 [email protected] 

EXEC sp_executesql @sql 

------------------------------------ 

Я надеюсь, что он будет работать

+0

Благодарим вас за этот фрагмент кода, который может предоставить Некоторая ограниченная краткосрочная помощь. Правильное объяснение [значительно улучшило бы] (// meta.stackexchange.com/q/114762) его долгосрочную ценность, показав * почему * это хорошее решение проблемы и сделало бы его более полезным для будущих читателей с другие, подобные вопросы. Пожалуйста, отредактируйте свой ответ, чтобы добавить какое-то объяснение, включая сделанные вами предположения. –

0

Если эта таблица BIG я думаю, что ваш и в вашей логике вы делаете JOINS с этой таблицей необходимо создать индексы в таблице назначения

Вы можете ходить с физической таблицей не 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 [email protected] --create the TargetTable 


--DO YOUR logic 

EXEC sp_executesql @sql 

set @sql = N'DROP TABLE ' + @tableName 

EXEC sp_executesql @sql 
0

Попробуйте это.

 
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 
+0

Благодарим вас за этот фрагмент кода, который может предоставить некоторую ограниченную краткосрочную помощь. Правильное объяснение [значительно улучшило бы] (// meta.stackexchange.com/q/114762) его долгосрочную ценность, показав * почему * это хорошее решение проблемы и сделало бы его более полезным для будущих читателей с другие, подобные вопросы. Пожалуйста, отредактируйте свой ответ, чтобы добавить какое-то объяснение, включая сделанные вами предположения. –

0

Вот еще одно решение с полностью динамическими столбцами:

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('''[email protected]+''') is not null) DROP TABLE '[email protected]+' 
CREATE TABLE '[email protected]+' ('[email protected]+')'+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 '[email protected]+char(10)+'SELECT '[email protected]+char(10)[email protected] 
print (@sql) 
exec (@sql) 

Это не будет работать, если вы подставляются myTempTable с #myTempTable из SQL двигателя. Чтобы исправить это и получить правильный список имен столбцов, вы можете использовать некоторые трюки, выходящие за рамки. Но все же он работает с нетемпературными таблицами.

-1

Вы можете создавать инструкции ALTER, которые динамически изменяют структуру вашей таблицы. Ниже приведена временная таблица, но, конечно, подход также работает для обычных таблиц.

IF OBJECT_ID('tempdb..#temp') IS NOT NULL 
    BEGIN 
    DROP TABLE #temp 
    END 
CREATE TABLE #temp 
    (
    [CVRelID]  INT, 
    [CustomerID] INT, 
    [VendorID]  INT, 
    [TransactionID] INT 
    ) 

DECLARE @script VARCHAR(8000) 
SET  @script = 'ALTER TABLE #temp ADD ' 

SELECT @script = @script + QUOTENAME(SDName) + ' VARCHAR(100),' 
FROM tblSupportDocuments 
WHERE SDIsActive = 1 


SET  @script = SUBSTRING(@script, 1, LEN(@script) - 1)-- remove last "," 
PRINT @script 
EXEC (@script) 
+3

Благодарим вас за этот фрагмент кода, который может предоставить некоторую ограниченную краткосрочную помощь. Правильное объяснение [значительно улучшило бы] (// meta.stackexchange.com/q/114762) его долгосрочную ценность, показав * почему * это хорошее решение проблемы и сделало бы его более полезным для будущих читателей с другие, подобные вопросы. Пожалуйста, отредактируйте свой ответ, чтобы добавить какое-то объяснение, включая сделанные вами предположения. –

+0

@TobySpeight нормально, извините, я буду иметь в виду в следующий раз. – fgohil

+0

Хотя мой ответ правильный, но, поскольку он проголосовали, никто не заглянет в него. Что нужно сделать для преодоления этой проблемы. – fgohil