为什么即使我在不​​退出子查询的地方使用,我的新记录插入也不起作用?

时间:2014-02-12 02:39:32

标签: sql sql-server

这是我用来创建表格的脚本。

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[ODSCustomerBase]') AND type in (N'U'))
DROP TABLE [ODSCustomerBase]
Go
Create Table ODSCustomerBase
(CustomerBaseID             int NOT NULL identity primary key,
RecordSource            nvarchar(4),
RecordType              varchar(2),
SiteURN             nvarchar(128)NOT NULL,
SiteDesc                    nvarchar(60)NULL,
CustomerLink            nvarchar(120)NOT NULL,
HomeCurrencyCode            nvarchar(8)NOT NULL, 
CustomerID                  nvarchar(15)NOT NULL,
CustomerCurrencyCode        nvarchar(8)NOT NULL,
CustomerName            nvarchar(120)NULL,
CustomerShortName           nvarchar(30) NOT NULL,
Address             nvarchar(255)NULL,
City                nvarchar(25)NULL,
PostalCode              nvarchar(10) NULL,
CountryCode             nvarchar(3) NOT NULL,
CountryName             nvarchar(60) NOT NULL,
StateCode               nvarchar(8) NULL,
StateName               nvarchar(60) NULL,
Phone               nvarchar(30) NOT NULL,
Fax                 nvarchar(30) NULL,
TaxCode             nvarchar(15) NULL,
ProspectID              nvarchar(15) NULL,
CreateDate              datetime NOT NULL,
LastUpdateDate          datetime NULL)

这是我用来插入第一次

的记录的脚本
insert into SEC_ODS.dbo.ODSCustomerBase

select 
--Identity as CustomerBaseID
'E4SE' as Recordsource, --could be others, eg 'BST', CRM, nvarchar(4)'
'C' as RecordType, --could be 'p'as prospects, add a case statement
ss.siteURN,
ss.sitedesc,
ss.FS_URL + 'frmcustomer.aspx?CustomerID=' + customerid as CustomerLink,
co.HomeCurrencyCode, 
c.customerid, 
c.currencycode as customercurrencycode,
c.entityname as CustomerName, 
c.entityshortname CustomerShortName, 
c.address, 
c.city, 
c.postalcode, 
c.countrycode, 
cn.countryname, 
c.statecode,
s.statename, 
c.phone,
c.fax, 
c.taxcode, 
c.prospectid,
c.createdate, 
c.lastupdatedate 
from country cn, 
SECSite ss, 
company co, 
customer c 
left outer join state s 
on c.statecode = s.statecode
where  ss.LocalSiteFlag = 1
and cn.countrycode = c.countrycode

因此,如果我使用此脚本检查ODS表,它会给我4395个结果

use sec_ods
go
select count(*) from  ODSCustomerBase

enter image description here

虽然这是我用来插入仅限新记录的脚本。这是我使用where not exists条件和子查询不起作用的地方,因为它使记录数量加倍。目标是只插入新记录。

insert into SEC_ODS.dbo.ODSCustomerBase

select 
--Identity as CustomerBaseID
'E4SE' as Recordsource, --could be others, eg 'BST', CRM, nvarchar(4)'
'C' as RecordType, --could be 'p'as prospects, add a case statement
ss.siteURN,
ss.sitedesc,
ss.FS_URL + 'frmcustomer.aspx?CustomerID=' + customerid as CustomerLink,
co.HomeCurrencyCode, 
c.customerid, 
c.currencycode,
c.entityname, 
c.entityshortname, 
c.address, 
c.city, 
c.postalcode, 
c.countrycode, 
cn.countryname, 
c.statecode,
s.statename, 
c.phone,
c.fax, 
c.taxcode, 
c.prospectid,
c.createdate, 
c.lastupdatedate 
from country cn, 
SECSite ss, 
company co, 
customer c 
left outer join state s 
on c.statecode = s.statecode
where  ss.LocalSiteFlag = 1
and cn.countrycode = c.countrycode

and not exists(select * from SEC_ODS.dbo.ODSCustomerBase b
                where(Recordsource=b.Recordsource and
                      RecordType=b.RecordType and
                      ss.siteURN=b.siteURN and 
                      ss.sitedesc=b.sitedesc and 
                      ss.FS_URL=b.CustomerLink and 
                      co.HomeCurrencyCode=b.HomeCurrencyCode and 
                      c.customerid=b.customerid and 
                      c.currencycode=b.CustomerCurrencyCode and 
                      c.entityname=b.CustomerName and 
                      c.entityshortname=b.CustomerShortName and 
                      c.address=b.address and 
                      c.city=b.city and 
                      c.postalcode=b.postalcode and 
                      c.countrycode=b.countrycode and 
                      cn.countryname=b.countryname and 
                      c.statecode=b.statecode and 
                      s.statename=b.statename and 
                      c.phone=b.phone and 
                      c.fax=b.fax and 
                      c.taxcode=b.taxcode and 
                      c.prospectid=b.prospectid and 
                      c.createdate=b.createdate and 
                      c.lastupdatedate=b.lastupdatedate))

因此,如果我使用此脚本检查ODS表,它会为我提供 8790 结果,这是错误的。

use sec_ods
go
select count(*) from  ODSCustomerBase

enter image description here

有人可以帮帮我吗? 谢谢。

enter image description here
enter image description here

2 个答案:

答案 0 :(得分:0)

在可能为NULL的所有字段周围使用ISNULLCOALESCE。 例如ISNULL(c.address,'')= ISNULL(b.address,'')

答案 1 :(得分:0)

如果您想更好地限制已插入的数据以进入合并语句,它将只更新现有数据或插入新数据

MERGE ODSCustomerBase AS T
    USING (
        SELECT Col1,col2,.... FROM ODSCustomerBase

        ) AS S
        ON (
                t.Col1 = s.Col1
                AND t.Col2 = s.Col2
                AND .....

                )
    WHEN NOT MATCHED BY TARGET
        THEN
            INSERT (
                Col1
                ,Col2
                ,....
                ,....
                )
            VALUES (
                S.Col1
                --,S.NrID
                ,s.Col2
                ,s.Col3

                )
    WHEN MATCHED
        THEN
            UPDATE
            SET T.Col1 = S.Col1
    WHEN NOT MATCHED BY SOURCE
        AND EXISTS (
            SELECT 1
            FROM ODSCustomerBase c
            WHERE t.Col1 = Col1

            )
        THEN
            DELETE;