【问题标题】:Inserting a Row of Default Values into a Temporary Table将一行默认值插入临时表
【发布时间】:2018-02-06 06:25:25
【问题描述】:

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

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

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

【问题讨论】:

    标签: sql sql-server temp-tables


    【解决方案1】:

    您需要创建临时表并在其中包含默认定义。

    --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】:

      从 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;
      

      【讨论】:

        【解决方案3】:

        当您通过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 |
        +------+--------+------------+
        

        【讨论】:

          猜你喜欢
          • 2013-07-02
          • 1970-01-01
          • 1970-01-01
          • 2011-07-20
          • 2016-07-01
          • 2019-02-25
          • 2018-03-02
          • 2013-01-14
          • 1970-01-01
          相关资源
          最近更新 更多