在INSERT INTO SELECT查询中将NULL转换为目标列的默认值

时间:2015-03-20 11:28:50

标签: sql-server

是否可以解决此问题而无需在每个查询中指定(并维护)静态类型列列表?

DECLARE @src TABLE (Id INT, Created DATETIME)

INSERT INTO @src
VALUES (1, NULL)

DECLARE @dst TABLE (Id INT, Created DATETIME DEFAULT GETDATE() NOT NULL)

INSERT INTO @dst
   SELECT *
   FROM @src

错误:

  

无法将值NULL插入列'Created',表'@dst';列不允许空值。

INSERT失败。

4 个答案:

答案 0 :(得分:0)

为什么你指定NOT NULL呢?如果仅指定了列,则触发默认值,这意味着您不会将任何值插入该列。但是在您的情况下,您将NULL值插入表中。如果你愿意的话:

insert into @dst(id) select id from @src

它会插入默认约束。如果插入NULL,则可以使用触发器将值更改为GETDATE()。

答案 1 :(得分:0)

使用静态表定义然后选择"选择*"要填写它,您必须确保列顺序正确并且表格在此期间未被修改,这可能会影响结果。它充满危险,容易出问题。更好的途径是使用SELECT INTO和临时表。如果之前没有创建表格模式,则SELECT INTO将创建表格模式,从而无需声明表格模式。

SELECT 1 AS [ID], CASE WHEN s.val IS NULL Then GETDATE() ELSE s.Val END as [Created Date]
INTO #src
FROM Source s

SELECT s.* 
INTO #dst d
from #src s

您可以在select语句中强制转换值,以便在需要时使用创建的临时表列类型或Put Case语句逻辑。

答案 2 :(得分:0)

我不确切地知道你在尝试什么,但这是有效的,因为它的表变量我不认为这样使用它有问题,我认为更有价值

DECLARE @src TABLE (Id INT, Created DATETIME)
INSERT INTO @src VALUES (1, NULL)
INSERT INTO @src VALUES (1, '2015-01-01')

DECLARE @dst TABLE (Id INT, Created DATETIME NOT NULL)
INSERT INTO @dst
SELECT s.Id,
       CASE WHEN s.Created IS NULL THEN GETDATE() ELSE s.Created END
FROM   @src s

SQLFidlle:http://sqlfiddle.com/#!6/9eecb/1367

答案 3 :(得分:0)

您可以尝试以下代码:

declare @src table (Id int, Created datetime)
insert into @src values(1, null)

declare @dst table (Id int, Created datetime default getdate() not null)
insert into @dst 
select 
    Id,
    COALESCE(Created, GETDATE())
from @src

因此,如果在第一个表(列Created)中插入一些日期然后执行第二个查询,则第二个表将填充第一个表中的值。如果你甚至想要在第一个表中插入NULL,那么在第二个查询中你必须做一些解决方法,不允许将显式NULL写入第二个表(即。COALESCE)。

当然,如果您在第二个查询中省略Created列,则会触发DEFAULT约束,并且它将自行插入GETDATE()值。