我的T-SQL语法有什么问题?
尝试运行此语句时,我不断收到以下错误消息。我在SSIS中的OLEDB命令中运行它 “')附近的语法不正确 显然,这是一个易于阅读的错误消息,但我不知道为什么我会收到它。我已经查看了T-SQL文档,我非常确定在需要的地方有括号我的T-SQL语法有什么问题?,sql,sql-server,tsql,Sql,Sql Server,Tsql,尝试运行此语句时,我不断收到以下错误消息。我在SSIS中的OLEDB命令中运行它 “')附近的语法不正确 显然,这是一个易于阅读的错误消息,但我不知道为什么我会收到它。我已经查看了T-SQL文档,我非常确定在需要的地方有括号 INSERT INTO dbo.Table1 ( [ID], [Supplier], [Level], [Status], [Core], [Location], [Outsourced], [Contac
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
)
)
更新
马丁·史密斯在阿里先生的回答上写了一篇很棒的文章——你确定你在这里做的事情是正确的吗?如果两个表中任何列中的任何值不同,select语句将返回该值。这意味着,如果表2中有一条记录,除了表1中有一条记录外,其他值都相同,则select语句将返回该记录,并且您可能会在表1中得到重复最严重的行(除了该单列)的主键冲突错误。
考虑到这一点,您可能应该从表2中选择表1中不存在键列的所有记录—任何作为唯一约束或索引一部分的列,而不仅仅是主键 因此,假设
ID
是主键,并且为了演示,您在电话
和电子邮件
上有一个唯一的索引,您需要的是如下内容:
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)
)
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 ... )
第一版
中的操作符的工作方式与SQL Server中的不同。它的左侧只能有一个操作数,右侧可以有多个操作数,因此它基本上将单个值与列表进行比较。
T-SQL在
操作符中的工作方式如下:
Col IN(value1, value2....valuen)
相当于
Col = value1 or Col = value2....or Col = valuen`
它在标准SQL中有效,有些数据库支持它,如MySql,但SQLServer不支持
您正在寻找:
在中,只有一个列名位于左侧,不能将列列表置于左侧。老实说,我不太确定你来这里干什么。。。这没有多大意义。但你可能想要更像这样的东西:
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)
)
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 ... )
但也许你的意思更像这样:
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)
)
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 ... )
使用Exists
可以提供更快的查询,有时甚至比righttable.PK_列为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]
)
WHERE
子句中的NOT
不是正确的T-SQL。无法使用该语法验证多个值。SQL Server不支持其中(a、b、c)不在(选择…)
您需要将其重写为不存在的相关子项-query@Igor:这是正确的“SQL”,它只是对T-SQLGeez无效。这些是大量有用的答案,我没想到会有这么多这么快。我将很快对它们进行测试,并接受任何最快的。您忽略了告诉我们您正试图用它做什么。这与元组的语义不同,不在中。鉴于他的语法,我不确定他到底在尝试什么。。。我一点也不清楚。我只是尽量把它翻译成一个真正的“IN”语法。这个语法已经是一个真正的语法了——只是SQL Server目前不支持这种语法。它将跨同一行中的列进行查看-如果Id存在于另一个表中,或者供应商存在于另一个表中,即使行不同,重写也将返回false。我只使用SQL Server。我以前从未见过如此奇怪的语法。老实说,我不知道他到底想干什么。哦,好吧。如果你必须猜测他们在尝试什么,那么没有义务发布答案。看看“除外”是慢还是快,然后不存在,这将是一件有趣的事情。我的猜测是,它们将以几乎相同的速度运行,甚至可能有相同的执行计划。我不得不说,IMHO,except在这种情况下更合适。tbh我不相信本页上的任何答案真的给出了所需的语义。如果行存在,但某些列的值不同,OP真的需要重复的id值吗?@MartinSmith很好!然而,我认为阿里先生的回答和我的回答都能满足OP的要求。如果这是正确的做法或不正确的做法-好吧,这是一个很好的问题,我同意这可能是错误的做法。这个问题的更新答案正是我所需要的(除了主键之外,对任何东西都没有唯一的限制)。感谢您和@Martin的回答,以及所有帮助我解决这个问题的人。很高兴提供帮助,但如果没有Martin的赞扬,我自己可能不会想到这一点……他没有发布自己的答案,我一直希望stack overflow能够以某种方式奖励那些在讨论中做出重大贡献而没有提供正式答案的人。比如代表礼物或类似的东西。嗯,我不确定你或我能给一个拥有316K代表的人多大的声誉,这实际上会有所不同。。。我想你还得问一些问题,希望他能回答:——)