2017-08-28 36 views
1

我正在嘗試從表中選擇一行默認值。但是,我不想在原始表格中創建一個新行。我的原始表具有爲所有列定義的非空默認值(全部爲空或零)(除了唯一的唯一標識符)。我首先創建一個臨時表:將一行默認值插入臨時表

SELECT 
    TOP 0 * 
INTO 
    #Table 
FROM 
    Database.dbo.Table 

然後我檢查空表:

SELECT 
    * 
FROM 
    #Table 

一切正常爲止。沒有行,但是我可以看到原始表中的所有列。於是,我試圖插入單行與默認值表中的所有列:

INSERT INTO 
    #Table 
DEFAULT VALUES 

而不是成功,我得到以下錯誤:

Cannot insert the value NULL into column 'Column', 
    table 'tempdb.dbo.#Table___0001A'; 
    column does not allow nulls. INSERT fails. 

接下來我試圖插入一個行只定義了一個字段。

INSERT INTO 
    #Table 
    (Column) 
VALUES 
    ('Value') 

相同的結果。看來我的原始表的列默認值的定義並未包含在臨時表的創建中。有什麼建議麼?

回答

0

您需要創建臨時表並在其中包含默認定義。

--Check to see if table exists 
--If it does, drop it 
IF OBJECT_ID('tempdb.dbo.#Table', 'U') IS NOT NULL 
    DROP TABLE #Table 

--Create temp table with default value 
CREATE TABLE #Table 
    (
     columnA INT DEFAULT (1), 
     columnB INT DEFAULT (2), 
     columnC INT DEFAULT (3) 
    ) 

--Insert a row of default values 
INSERT INTO 
#Table 
DEFAULT VALUES 

--See it 
SELECT * 
FROM #Table 

--Drop temp table after you are done 
DROP TABLE #Table 
0

從temptdb目錄建立你的行?

SELECT c.name                  AS 'Colunmn' 
,  TYPE_NAME(c.user_type_id)             AS 'Type' 
,  CASE c.is_nullable WHEN 0 THEN 'No Nulls' 
           ELSE '' END          AS 'Nullable' 
,  CASE c.default_object_id WHEN 0 THEN '' 
             ELSE 'Y' END         AS 'Has_Default' 
,  dft.definition                as Default_Value 
,  CASE ISNULL(c.max_length, -1) WHEN -1 THEN 'Variable' 
              ELSE CAST(c.max_length AS VARCHAR) END AS 'Length' 
,  ISNULL('['+OBJECT_NAME(fkc.referenced_object_id)+'].['+Cref.name+']', ' ') AS ForeignKeyInto 
FROM  tempdb.sys.tables    t 
JOIN  tempdb.sys.columns    c ON t.object_id = c.object_id 
LEFT JOIN tempdb.sys.foreign_key_columns FKC ON c.object_id = fkc.Parent_object_id 
     AND fkc.parent_column_id = c.column_id 
LEFT JOIN tempdb.sys.columns    cref ON fkc.referenced_column_id = cref.column_id 
     AND fkc.referenced_object_id = cref.object_id 
left join tempdb.sys.default_constraints dft on c.default_object_id = dft.object_id 
WHERE t.name like '#temp%' 
ORDER BY t.name 
,  c.name; 
1

當您通過SELECT ... INTO #Table創建臨時表臨時表會從主表中的所有列,但沒有約束或索引。

顯然,您可以使用所有必要的約束來顯式創建臨時表。

另外一個選擇是實際在主表中插入一行,讓引擎用默認值填充它,然後讀取插入的值並將它們插入臨時表中。所有這些在交易中。然後回滾事務,以便主表保持原樣。

爲了使它工作,您需要使用表變量而不是臨時表,因爲臨時表作爲普通表參與事務,但表變量不參與事務。這意味着你必須預先定義表格變量,所以你需要知道你的原始表格有哪些列。但是,至少,您不必知道默認約束的定義。另外,如果您的主表有一個INDENTITY列,則此插入回滾會在標識值中創建一個間隔。

樣品表

CREATE TABLE [dbo].[MainTable](
    [Col1] [int] NOT NULL, 
    [Col2] [nvarchar](50) NOT NULL, 
    [Col3] [date] NOT NULL 
) ON [PRIMARY] 
GO 

ALTER TABLE [dbo].[MainTable] ADD CONSTRAINT [DF_MainTable_Col1] 
DEFAULT ((123)) FOR [Col1] 
GO 

ALTER TABLE [dbo].[MainTable] ADD CONSTRAINT [DF_MainTable_Col2] 
DEFAULT ('qwerty') FOR [Col2] 
GO 

ALTER TABLE [dbo].[MainTable] ADD CONSTRAINT [DF_MainTable_Col3] 
DEFAULT (getdate()) FOR [Col3] 
GO 

查詢

DECLARE @T TABLE (Col1 int, Col2 nvarchar(50), Col3 date); 

BEGIN TRANSACTION; 

INSERT INTO dbo.MainTable 
OUTPUT inserted.Col1, inserted.Col2, inserted.Col3 
INTO @T (Col1, Col2, Col3) 
DEFAULT VALUES; 

ROLLBACK TRANSACTION; 

SELECT * 
FROM @T; 

結果

+------+--------+------------+ 
| Col1 | Col2 | Col3 | 
+------+--------+------------+ 
| 123 | qwerty | 2017-08-29 | 
+------+--------+------------+