查询似乎修改了不同的列

时间:2016-12-21 14:38:26

标签: sql sql-server tsql sql-insert

我正在尝试使用以下查询将数据从一个表插入到另一个表中,但是我收到的错误使我感到困惑。

查询

INSERT INTO [BILLING].[dbo].[Consolidated_Billing]
    ([Total Charge])
SELECT SUM(bt.[Service_Cost])
FROM [BILLING].[dbo].[Billing_Table] bt, [BILLING].[dbo].[Consolidated_Billing] cb
WHERE bt.NAME = cb.[Server Name]
AND bt.COST_CENTER = cb.[Cost Center]
AND bt.REMEDY_DIVISION = cb.Division;

错误

  

Msg 515,Level 16,State 2,Line 1

     

无法将值NULL插入“托管WS DEV”列,表'BILLING.dbo.Consolidated_Billing';列不允许空值。 INSERT失败。

虽然这一切都非常好(毕竟,主题'托管WS DEV'设置为NOT NULL),我想知道为什么insert语句甚至会影响该列?它不应该只是将值插入[Total Charge]列(可以为空)吗?

问题

为什么我的INSERT会影响其他列?我该如何修复错误?

备注

我对SQL没有多少经验,所以可能会在幕后发生我不知道的动作。我确实尝试修改查询以将SELECT更改为

SELECT IIF(SUM(bt.[Service_Cost]) IS NULL, 0, SUM(bt.[Service_Cost]))

但同样的错误仍然存​​在。我也试过使用LEFT JOIN& RIGHT JOIN无济于事。

修改

根据要求,这是表格架构。这有点儿太糟糕了。

CREATE TABLE [dbo].[Consolidated_Billing](
    [Server Name] [nvarchar](254) NULL,
    [Cost Center] [nvarchar](13) NULL,
    [Division] [nvarchar](32) NULL,
    [Billing Comments] [nvarchar](255) NULL,
    [Month] [nvarchar](50) NULL,
    [Year] [nvarchar](50) NULL,
    [Hosting WS DEV] [float] NOT NULL,
    [Hosting A] [float] NOT NULL,
    [Hosting DEV] [float] NOT NULL,
    [AppSerSup-Solaris Std] [float] NOT NULL,
    [AppSerSup-Virt Large Tier] [float] NOT NULL,
    [DS-Backup Tape Rec] [float] NOT NULL,
    [DR - Enhanced 12hr] [float] NOT NULL,
    [AppSerSup-Wintel-2Way] [float] NOT NULL,
    [Hosting Websphere] [float] NOT NULL,
    [AppSerSup-AIX Std] [float] NOT NULL,
    [AppSerSup-Solaris Mid] [float] NOT NULL,
    [Dr - Enhanced 4hr] [float] NOT NULL,
    [DR-IBM Rec Storage] [float] NOT NULL,
    [AppSerSup-Citrix Server] [float] NOT NULL,
    [AppSerSup-Linux Virtual] [float] NOT NULL,
    [AppSerSup-Virt Med Tier] [float] NOT NULL,
    [AppSerSup-Virt Dedicated] [float] NOT NULL,
    [AppSerSup-Virt Small Tier] [float] NOT NULL,
    [DS-High Perform SAN] [float] NOT NULL,
    [DR - Enhanced SAN] [float] NOT NULL,
    [AppSerSup-Wintel Physical] [float] NOT NULL,
    [AppSerSup-Virt Split] [float] NOT NULL,
    [DR-Level 1 Wintel] [float] NOT NULL,
    [AppSerSup-DB Support] [float] NOT NULL,
    [AppSerSup-Complex-Data Inf] [float] NOT NULL,
    [AppSerSup-Wintel Virtual] [float] NOT NULL,
    [AppSerSup-Unix/Linux Phy] [float] NOT NULL,
    [Hosting B] [float] NOT NULL,
    [AppSerSup-AIX Mid] [float] NOT NULL,
    [AppSerSup-Wintel-4Way] [float] NOT NULL,
    [DS-Standard SAN] [float] NOT NULL,
    [Total Charge] [float] NULL
) ON [PRIMARY]

2 个答案:

答案 0 :(得分:4)

您无法在一列中插入"&#34 ;;你在表中插入一行。在您插入的行中,该表的每一列都会获得一个值。

对于您在insert语句中指定的列,它们将获取您指定的值。其余的获取为表定义的默认值,如果没有指定默认值,则为NULL。因此,如果您没有为列提供值,并且它没有默认值,并且它是NOT NULL列,则插入失败。

<强>更新

从评论中,您真正想要的是更新声明

UPDATE myTable
   SET col1 = val1

会更改col1中每一行myTable的值;因为听起来你必须处理一个你想要单行的表,所以可以做你需要的。

如果表格有很多行而你只想影响其中一行,比如

UPDATE myTable
   SET col1 = val1
 WHERE col2 = val2
例如,

仅会更改col1中具有特定值的记录的col2

答案 1 :(得分:2)

查询影响其他列。插入新行时,未显式指定的列将初始化为其默认值,如果没有默认值,则为NULL。

必须明确指定没有默认值的非可空列。这适用于所有使用SQL的产品,而不仅仅是特定版本的SQL Server。

在您的情况下,似乎[Hosting WS DEV]是一个不可为空的列,没有任何默认值。您必须将它包含在INSERT语句中并为其添加一些值,例如:

INSERT INTO [BILLING].[dbo].[Consolidated_Billing]
    ([Total Charge], [Hosting WS DEV])
SELECT SUM(bt.[Service_Cost],'')
FROM [BILLING].[dbo].[Billing_Table] bt, [BILLING].[dbo].[Consolidated_Billing] cb
WHERE bt.NAME = cb.[Server Name]
AND bt.COST_CENTER = cb.[Cost Center]
AND bt.REMEDY_DIVISION = cb.Division;