7

Ho bisogno di inserire alcuni dati in una tabella temporanea.CREATE TABLE con Dynamic Column

mi hanno alcune colonne condizionali basati come Salary, Code.

Come posso creare una tabella per colonne condizionali? Non voglio usare SELECT INTO #tempTable

Ecco il codice:

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 

Qualsiasi aiuto/suggerimento su come meglio posso fare questo?


Aggiornamento:

Inizialmente ho usato SELECT INTO #TempTable senza specificare alcuna delle colonne, come SQL Azure non supportano questo, ho deciso di andare con INSERT INTO. Ma non sono sicuro di come sia possibile aggiungere già colonne dinamiche in una struttura definita. Il suo SQL completamente dinamico :(

+0

@MahmoudGamal, aggiornato la mia domanda. Vedere la parte di aggiornamento per ulteriori informazioni – Billa

+0

Non è possibile aggiungere colonne alle tabelle in modo dinamico. Devi avere tutte le colonne definite in anticipo. – dasblinkenlight

+0

@dasblinkenlight, Quindi ho bisogno di CREARE una tabella tra cui Salario, colonne di codice, anche se non sono in selezione? Se questo è il caso, quale ordine inserirà se seleziono solo 3 colonne? Scusa, non sono bravo in sql. – Billa

risposta

1

quante colonne dinamica ha bisogno?

Cosa ne dite di una colonna chiamata Dynamic di tipo nvarchar(MAX) o qualcosa di simile, e poi si può semplicemente mettere i dati in là e il formato . a seconda dei casi

Un'altra opzione è quella di creare una tabella con le colonne NULL

per fare questo in SQL, è possibile effettuare le seguenti operazioni:.

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

Si noti anche la colonna NULL precedente.

Vedi qui per ulteriori spiegazioni sulla creazione di tabelle con Primary Keys e NULL colonne in SQL:

Create tables in SQL

+0

Sono circa 10+ colonne. – Billa

+0

Come hai detto tu ne hai bisogno dinamicamente, ne hai bisogno tutti allo stesso tempo? – rhughes

+0

Suppongo di avere colonne predefinite 5 e prenderò 2 o più colonne che vengono aggiunte in una o più istruzioni If che soddisfano alcune condizioni – Billa

0

vedi esempio qui sotto:

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

Di seguito il codice può funzionare per voi.

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

Grazie per questo snippet di codice, che potrebbe fornire una guida limitata a breve termine. Una spiegazione appropriata [migliorerebbe notevolmente] (// meta.stackexchange.com/q/114762) il suo valore a lungo termine mostrando * perché * questa è una buona soluzione al problema e lo renderebbe più utile ai futuri lettori con altre domande simili. Per favore [modifica] la tua risposta per aggiungere qualche spiegazione, incluse le ipotesi che hai fatto. –

0

Si potrebbe semplicemente modificare la tabella temporanea quando la condizione è soddisfatta (sto assumendo si conoscono le colonne necessarie a questo punto?)

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

Si consiglia di verificare se esiste la colonna In primo luogo, se si dispone di più di una condizione che potrebbe essere attivato - che si può fare in questo modo:

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

come altri hanno notato, è possibile creare le colonne in anticipo come annullabile - o creare la tabella dopo il conditi su è incontrato.

0

si può utilizzare il comando

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

per cambiare il nome di una colonna segnaposto definito in precedenza. Ad esempio, creare #tempTable con campi aggiuntivi come "VCHAR100_1", "BOOL_1", "Int_1", ecc. Se è necessario utilizzare il campo, rinominarlo con il nome desiderato in modo che il codice in un secondo momento possa fare riferimento alla colonna in modo non criptico nome.

0

Penso che quello che stai cercando sia impossibile per SQL. Mentre ti accontento voglio aggiungere una colonna, per esempio tuple che soddisfano le condizioni. Quindi penso che tu abbia bisogno di altri motori di database come NoSQL (non ho molta familiarità con NoSQL ma per quanto ne so può scalare orizzontalmente)

Se non vuoi passare da sql penso che dovresti riconsiderare il tuo design.
Se insisti sul tuo design puoi fare cose come ad esempio aggiungere una colonna, il nome "nome colonna" e un'altra colonna "dati colonna" e riempirla quando è necessario. Ma come puoi vedere ha i suoi vincoli come i dati di "dati colonna" dovrebbero essere dello stesso tipo.

1

Come accennato, la soluzione migliore è probabilmente creare tutte le colonne necessarie e renderle Nullable se facoltative. Quindi:

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

E

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

utilizzare il codice e dirmi sta funzionando o no ??

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

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 

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

spero che funzionerà

+0

Grazie per questo frammento di codice, che potrebbe e qualche aiuto limitato a breve termine. Una spiegazione appropriata [migliorerebbe notevolmente] (// meta.stackexchange.com/q/114762) il suo valore a lungo termine mostrando * perché * questa è una buona soluzione al problema e lo renderebbe più utile ai futuri lettori con altre domande simili. Per favore [modifica] la tua risposta per aggiungere qualche spiegazione, incluse le ipotesi che hai fatto. –

0

Se questo tavolo è GRANDE Credo che la vostra e nella vostra logica fate unisce con questa tabella è necessario creare gli indici in TARGET TAVOLA

Si può andare in giro con tabella fisica non 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

Prova questo.

 
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

Grazie per questo snippet di codice, che potrebbe fornire una guida limitata a breve termine. Una spiegazione appropriata [migliorerebbe notevolmente] (// meta.stackexchange.com/q/114762) il suo valore a lungo termine mostrando * perché * questa è una buona soluzione al problema e lo renderebbe più utile ai futuri lettori con altre domande simili. Per favore [modifica] la tua risposta per aggiungere qualche spiegazione, incluse le ipotesi che hai fatto. –

0

Ecco un'altra soluzione con colonne completamente dinamici:

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) 

Questo non funzionerà se si substite myTempTable con #myTempTable a causa del motore SQL. Per risolvere il problema e ottenere l'elenco dei nomi delle colonne corretto, è possibile utilizzare alcuni trucchi che non rientrano nell'ambito di applicazione. Ma funziona ancora con tabelle non temporanee.

-1

È possibile generare istruzioni ALTER che alterano dinamicamente la struttura della tabella. Mostrato sotto con una tabella temporanea, ma ovviamente l'approccio funziona anche per le tabelle normali.

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

Grazie per questo snippet di codice, che potrebbe fornire una guida limitata a breve termine. Una spiegazione appropriata [migliorerebbe notevolmente] (// meta.stackexchange.com/q/114762) il suo valore a lungo termine mostrando * perché * questa è una buona soluzione al problema e lo renderebbe più utile ai futuri lettori con altre domande simili. Per favore [modifica] la tua risposta per aggiungere qualche spiegazione, incluse le ipotesi che hai fatto. –

+0

@TobySpeight ok, scusa ricorderò la prossima volta. – fgohil

+0

Anche se la mia risposta è corretta ma non è stata votata, nessuno la esaminerà. Cosa dovrebbe essere fatto per superare questo problema. – fgohil

Problemi correlati