一時テーブルにデータを挿入する必要があります。
いくつかの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 :(
ほのめかされているように、最善の策は、必要なすべての列を作成し、オプションの場合はそれらを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
動的列はいくつ必要ですか?
タイプnvarchar(MAX)
などのDynamic
という列を作成すると、データをそこに配置して、必要に応じてフォーマットできます。
もう1つのオプションは、NULL
列のテーブルを作成することです。
SQLでこれを行うには、次のようにします。
CREATE TABLE tblPerson
(
PersonId INT,
FirstName NVARCHAR(256),
LastName NVARCHAR(256) NULL,
PRIMARY KEY (PersonId)
)
上記のNULL
列にも注意してください。
SQLでPrimary Keys
列とNULL
列を使用してテーブルを作成する方法の詳細については、こちらを参照してください。
以下の例を参照してください。
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)
以下のコードがあなたのために働くかもしれません。
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
このテーブルが大きい場合は、ロジックでこのテーブルを使用してJOINSを作成し、TARGETTABLEでインデックスを作成する必要があると思います。
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
あなたが本当に探しているものはSQLでは不可能だと思います。よくわかりませんが、たとえば、条件を満たすタプルの列を追加する必要があります。したがって、NoSQLのような他のデータベースエンジンが必要だと思います(私はNoSQLにあまり詳しくありませんが、水平方向に拡張できることを知っています)
SQLから切り替えたくない場合は、設計を再検討する必要があると思います。
デザインを主張する場合は、たとえば、列、名前「列名」、別の列「列データ」を追加し、必要に応じて入力するなどの操作を行うことができます。ただし、ご覧のとおり、「列データ」のデータは同じタイプである必要があるなど、独自の制約があります。
これを試して。
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 Id、DeptID、DeptName、Salary、Code Fromdbo.Employeeを選択します ドロップテーブル#myTempTable 終了 その他 開始 CREATE TABLE# myTempTable2(Id INT、DeptId INT、DeptName VARCHAR(100)) Insert Into #myTempTable(Id、DeptId、DeptName) Emp.Id、Emp.DeptID、Empを選択します.DeptName From dbo.Employee As Emp Select Id、DeptID、DeptName From dbo.Employee Drop Table#myTempTable2 終わり[。__ __。] コミットトラン
条件が満たされたときに一時テーブルを変更することもできます(この時点で必要な列を知っていると思いますか?)
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
他の人が指摘しているように、列をnull許容として事前に作成するか、条件が満たされた後にテーブルを作成することができます。
使用できますか
sp_RENAME 'TableName.[OldColumnName]' , '[NewColumnName]', 'COLUMN'
以前に定義したプレースホルダー列の名前を変更するコマンド。
たとえば、#tempTable
、"VCHAR100_1"
、"BOOL_1"
などの追加フィールドを使用して"Int_1"
を作成します。フィールドを使用する必要がある場合は、名前を変更します。後でコードが非暗号名で列を参照できるように、目的の名前に変更します。
完全に動的な列を使用した別のソリューションを次に示します。
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に置き換えると、これは機能しません。それを修正して正しい列名リストを取得するには、範囲外のいくつかのトリックを使用できます。ただし、それでも非一時テーブルでは機能します。
コードを使用して、それが機能しているかどうかを教えてください??
-----------------------------------------------------
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
------------------------------------
私はそれがうまくいくことを願っています