SQL返回所有行,如果为;在;子查询失败
所以最近我给自己带来了很多麻烦,因为我编码太快,没有很好地测试我的代码,并且发布了一个编译器没有捕获到的错误的存储过程。我有这样一个问题:SQL返回所有行,如果为;在;子查询失败,sql,sql-server,tsql,stored-procedures,Sql,Sql Server,Tsql,Stored Procedures,所以最近我给自己带来了很多麻烦,因为我编码太快,没有很好地测试我的代码,并且发布了一个编译器没有捕获到的错误的存储过程。我有这样一个问题: --Lets say I have a table SomeTable (SomeId, CreateDate, UpdatedDate) DECLARE @Temp TABLE (Id INT); INSERT INTO @Temp (Id) SELECT SomeId FROM SomeTable WHERE CreateDate > Some
--Lets say I have a table SomeTable (SomeId, CreateDate, UpdatedDate)
DECLARE @Temp TABLE (Id INT);
INSERT INTO @Temp (Id)
SELECT SomeId FROM SomeTable WHERE CreateDate > SomeDate;
UPDATE SomeTable
SET UpdatedDate = GETDATE()
WHERE SomeId IN (SELECT TempId FROM @Temp);
现在编译器没有发现我试图在子查询中选择一个临时表(我得到的)中不存在的列。然而,在我看来,如果子查询在这种情况下失败,那么不返回任何行就没有意义了。当我运行此命令时,SomeTable中的每一行都被更新。你可以想象,这是一个巨大的痛苦来修复。有人知道它为什么这样做吗?我似乎在网上找不到答案。你认为你写了这个查询:
UPDATE SomeTable s
SET UpdatedDate = GETDATE()
WHERE s.SomeId IN (SELECT t.TempId FROM @Temp t);
但是,如果t.TempId
不存在,则SQL Server(和所有其他数据库)将其解释为:
UPDATE SomeTable s
SET UpdatedDate = GETDATE()
WHERE s.SomeId IN (SELECT s.TempId FROM @Temp t);
如果您要获取所有行,则有一列SomeTable.TempId
,该列的值与SomeTable.SomeId
相同。我猜你在这两个地方使用了相同的列名。因此,您的查询本质上是SomeTable.SomeId=SomeId
——只要SomeId
不是NULL
,这一点都是正确的
如果遵循始终使用表别名限定列名的bets实践,则不会出现此问题。如果您这样做了,那么查询的第一个版本可能会失败,可能会出现可理解的错误。您认为您编写了以下查询:
UPDATE SomeTable s
SET UpdatedDate = GETDATE()
WHERE s.SomeId IN (SELECT t.TempId FROM @Temp t);
但是,如果t.TempId
不存在,则SQL Server(和所有其他数据库)将其解释为:
UPDATE SomeTable s
SET UpdatedDate = GETDATE()
WHERE s.SomeId IN (SELECT s.TempId FROM @Temp t);
如果您要获取所有行,则有一列SomeTable.TempId
,该列的值与SomeTable.SomeId
相同。我猜你在这两个地方使用了相同的列名。因此,您的查询本质上是SomeTable.SomeId=SomeId
——只要SomeId
不是NULL
,这一点都是正确的
如果遵循始终使用表别名限定列名的bets实践,则不会出现此问题。如果您这样做了,那么查询的第一个版本可能会失败,可能会出现可理解的错误。SomeTable是否包含列名
TempId
?如果是,那么SQL标准就是这样定义子选择中列的可见性的;这只是一个即时的例子。这不是真正的代码。是否SomeTable
包含列名TempId
?如果是,那么SQL标准就是这样定义子选择中列的可见性的;这只是一个即时的例子。这不是真正的代码。如果tempId
在子选择中使用别名限定,那么它应该抛出一个错误。只有当列名没有使用别名(或表名)限定时,子选择中的列名才会出现歧义。别名本来可以让我避免麻烦。不知道为什么我没有想到。如果tempId
在子选择中用别名限定,那么它应该抛出一个错误。只有当列名没有使用别名(或表名)限定时,子选择中的列名才会出现歧义。别名本来可以让我避免麻烦。不知道为什么我没想到。