我的T-SQL语法有什么问题?

问题描述 投票:0回答:3

当我尝试运行此语句时,我不断收到以下错误消息。我在SSIS中的OLE DB命令中运行它。

')附近的语法不正确

显然这是一个易于阅读的错误消息,但我不知道为什么我会得到它。我检查了T-SQL文档,我很确定我需要它们的括号。

INSERT INTO
  dbo.Table1 (
    [ID],
    [Supplier],
    [Level],
    [Status],
    [Core],
    [Location],
    [Outsourced],
    [Contact],
    [Phone],
    [Email]
  )
SELECT
  [ID],
  [Supplier],
  [Level],
  [Status],
  [Core],
  [Location],
  [Outsourced],
  [Contact],
  [Phone],
  [Email]
FROM
  dbo.Table2
WHERE
  NOT (
    [ID],
    [Supplier],
    [Level],
    [Status],
    [Core],
    [Location],
    [Outsourced],
    [Contact],
    [Phone],
    [Email] IN (
      SELECT
        [ID],
        [Supplier],
        [Level],
        [Status],
        [Core],
        [Location],
        [Outsourced],
        [Contact],
        [Phone],
        [Email]
      FROM
        dbo.table1
    )
  )
sql sql-server tsql
3个回答
6
投票

更新

马丁史密斯在M.Ali的答案上写了一篇很棒的comment - 你确定你在这里做的正确吗?如果任何列中的任何值在两个表中都不同,则select语句将返回它。 这意味着如果表2中的记录具有所有相同的值,除了表1中具有记录的记录,则select语句将返回它,并且您可能得到最坏的主键违规错误 - 重复的行(除了表1中的那一列)。 考虑到你应该做的是从表2中选择表1中不存在关键列的所有记录 - 任何唯一约束或索引的一部分,而不仅仅是主键。

因此,假设ID是主键,并且为了演示你在PhoneEmail上有一个独特的索引,你需要的是这样的:

INSERT INTO
  dbo.Table1 (
    [ID],
    [Supplier],
    [Level],
    [Status],
    [Core],
    [Location],
    [Outsourced],
    [Contact],
    [Phone],
    [Email]
  )
SELECT
  [ID],
  [Supplier],
  [Level],
  [Status],
  [Core],
  [Location],
  [Outsourced],
  [Contact],
  [Phone],
  [Email]
FROM
  dbo.Table2 t2
WHERE NOT EXISTS
(
    SELECT 1
    FROM Table1 t1
    WHERE t1.ID = t2.ID
    OR (t1.Phone = t2.Phone AND t1.Email = t2.Email)
)

第一版

IN运算符在SQL Server中的工作方式不同。它左侧只能有一个操作数,权限方面有许多操作数,因此它基本上将单个值与列表进行比较。 T-SQL IN运算符的工作方式如下:

Col IN(value1, value2....valuen)

相当于

Col = value1 or Col = value2....or Col = valuen`   

它在标准SQL中有效,并且有支持它的数据库,如MySql,但SQL Server没有。

您正在寻找EXCEPT

INSERT INTO
  dbo.Table1 (
    [ID],
    [Supplier],
    [Level],
    [Status],
    [Core],
    [Location],
    [Outsourced],
    [Contact],
    [Phone],
    [Email]
  )
SELECT
  [ID],
  [Supplier],
  [Level],
  [Status],
  [Core],
  [Location],
  [Outsourced],
  [Contact],
  [Phone],
  [Email]
FROM
  dbo.Table2
EXCEPT 
      SELECT
        [ID],
        [Supplier],
        [Level],
        [Status],
        [Core],
        [Location],
        [Outsourced],
        [Contact],
        [Phone],
        [Email]
      FROM
        dbo.table1

2
投票

使用Exists可以为您提供更快的查询,有时甚至比left join where righttable.PK_Column is null查询更快。

INSERT INTO dbo.Table1 
          ([ID],[Supplier],[Level],[Status],[Core],[Location]
            ,[Outsourced],[Contact],[Phone],[Email])
SELECT
  [ID],
  [Supplier],
  [Level],
  [Status],
  [Core],
  [Location],
  [Outsourced],
  [Contact],
  [Phone],
  [Email]
FROM
  dbo.Table2 t2
WHERE NOT EXISTS ( SELECT 1 
                   FROM dbo.table1 t1
                    WHERE t2.[ID]        = t2.[ID]
                          t2.[Supplier]  = t2.[Supplier]
                          t2.[Level]     = t2.[Level]
                          t2.[Status]    = t2.[Status]
                          t2.[Core]      = t2.[Core]
                          t2.[Location]  = t2.[Location]
                          t2.[Outsourced]= t2.[Outsourced]
                          t2.[Contact]   = t2.[Contact]
                          t2.[Phone]     = t2.[Phone]
                          t2.[Email]     = t2.[Email] 
                  )

0
投票

IN在左侧只有一个列名,您不能在左侧列出列。老实说,我不确定你在这里会发生什么......它没有多大意义。但你可能想要更像这样的东西:

WHERE
    [ID] NOT IN (SELECT [ID] FROM dbo.Table1)
AND [Supplier] NOT IN (SELECT [Supplier] FROM dbo.Table1)
AND ...

但也许你的意思是这样的:

WHERE NOT EXISTS (SELECT 1 FROM dbo.Table1 WHERE Table1.ID = Table2.ID 
                                             AND Table1.Supplier = Table2.Supplier 
                                             AND ... )
© www.soinside.com 2019 - 2024. All rights reserved.