将一行默认值插入临时表

时间:2017-08-28 22:33:59

标签: sql sql-server temp-tables

我试图从表格中选择一行默认值。但是,我不想在原始表格中创建新行。我的原始表具有为所有列定义的非空默认值(所有空白或零)(除了一个唯一标识符)。我首先创建临时表:

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

相同的结果。看来我原始表中列默认值的定义未包含在临时表的创建中。有什么建议吗?

3 个答案:

答案 0 :(得分: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 |
+------+--------+------------+

答案 1 :(得分: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

答案 2 :(得分: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;