我需要将一些数据插入到临时表中。
我有一些 基于条件的列,例如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 +@sqlFrom
EXEC sp_executesql @sql
关于我能做得更好的任何帮助/建议?
更新
最初我使用SELECT INTO #TempTable
而没有指定列数,因为SQL Azure不支持,我决定使用INSERT INTO
。但不确定如何在已定义的结构中添加动态列。它的完全动态SQL :(
答案 0 :(得分:1)
您需要多少个动态列?
如果有一个名为Dynamic
的{{1}}类型的列或类似内容,那么您可以将数据放在那里并根据需要进行格式化。
另一种选择是创建一个包含nvarchar(MAX)
列的表。
要在SQL中执行此操作,您可以执行以下操作:
NULL
请注意上面的CREATE TABLE tblPerson
(
PersonId INT,
FirstName NVARCHAR(256),
LastName NVARCHAR(256) NULL,
PRIMARY KEY (PersonId)
)
列。
有关在SQL中创建包含NULL
和Primary Keys
列的表格的详细说明,请参阅此处:
答案 1 :(得分:1)
如上所述,您最好的选择是创建所需的所有列,并在可选时将其设置为NULL。所以:
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
答案 2 :(得分: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)
答案 3 :(得分: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 +@sqlFrom
EXEC sp_executesql @sql
答案 4 :(得分: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
正如其他人所说,您可以将列预先创建为可为空的列 - 或者在满足条件后创建表。
答案 5 :(得分:0)
可以使用
吗?sp_RENAME 'TableName.[OldColumnName]' , '[NewColumnName]', 'COLUMN'
命令用于更改先前定义的占位符列的名称
例如,使用#tempTable
,"VCHAR100_1"
,"BOOL_1"
等额外字段创建"Int_1"
。如果您需要使用该字段,请将其重命名为所需名称,以便稍后您的代码可以通过非神秘的名称引用该列。
答案 6 :(得分:0)
我认为你真正想要的是SQL不可能。因为我想要添加列,例如符合条件的元组。所以我认为你需要一些像NoSQL这样的其他数据库引擎(我对NoSQL不是很熟悉,但我知道它可以横向扩展)
如果你不想从sql切换,我认为你应该重新考虑你的设计。
如果你坚持你的设计,你可以做一些事情,例如添加一个列,命名“列名”和另一列“列数据“并在需要时填写。但是你可以看到它有自己的约束,比如“列数据”的数据应该是相同的类型。
答案 7 :(得分: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 +@sqlFrom
EXEC sp_executesql @sql
------------------------------------
我希望它会起作用
答案 8 :(得分:0)
如果这个表很大,我认为你和你的逻辑你用这个表做JOINS你需要在TARGET TABLE中创建索引
你可以使用物理表而不是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
答案 9 :(得分: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
答案 10 :(得分: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('''+@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)
如果因为SQL引擎而将myTempTable替换为#myTempTable,则无效。要修复它并获得正确的列名列表,您可能会使用超出范围的一些技巧。但它仍适用于非临时表。
答案 11 :(得分:-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)