使用 pyodbc 和 SQL Server,如何在跳过 NULL 行时将行插入表中



我的代码成功跳过了重复的行,但它允许插入超过1个NULL行。我想忽略第3行和第4行的插入,以便只有1个空行(我的数据集中有很多缺失的数据(。

RegionID    province    country
1          QC       CAN                      
2         NULL      NULL
3         NULL      NULL
4         NULL      NULL
5          ON       CAN                      
6          AB       CAN                      
7          PA       USA                      
8          VA       USA     
9         NULL      USA                      

我尝试在插入语句中添加变体,但没有成功。我尝试过的:

"WHERE(省=?,国家=?(
1-AND(省份不为空,国家/地区不为空(
2-OR(省份不为空,国家或地区不为零(

我的代码:

import pyodbc

cursor.execute((BEGIN
IF NOT EXISTS (SELECT province, country FROM dbo.Region
WHERE (province = ? AND country = ?) )
BEGIN
INSERT INTO dbo.Region (province, country)
VALUES (?,?)
END
END),province_py,country_py,province_py,country_py)
conn.commit()

我还尝试使用此查询删除SQL中的第3行和第4行,但有0行受到影响。

DELETE FROM Region
WHERE province IS NULL and country IS NULL;

首先要记住的是,NULL不能与任何具有=的东西进行比较这是因为NULL表示UNKNOWN,因此谓词WHERE 5 = NULL产生UNKNOWN,而WHERE必须产生TRUE。不仅如此,NULL = NULL也因的相同原因而失败

解决此问题的标准方法使用一些相当麻烦的AND/OR逻辑:

IF NOT EXISTS (SELECT 1    -- NOT EXISTS doesn't care what you select unless there are other predicates
FROM dbo.Region
WHERE ( (province = @province OR  @province IS NULL AND province IS NULL)
AND (country = @country OR    @country IS NULL AND country IS NULL)
) )
BEGIN
INSERT INTO dbo.Region (province, country)
VALUES (@province, @country)
END;

但还有更好的解决方案。这使用INTERSECT,正如您所期望的那样,它考虑了null:

IF NOT EXISTS (
SELECT @province, @country
INTERSECT
SELECT province, country
FROM dbo.Region)
BEGIN
INSERT INTO dbo.Region (province, country)
VALUES (@province, @country)
END;

这里的逻辑是:创建一个一行的参数虚拟表。将其与表Region中那些列上的任何匹配项相交。然后CCD_ 13询问是否没有结果。

切换到IF EXISTSEXCEPT也可以做同样的事情


我建议您使用正确命名的参数@province,而不是?

相关内容

  • 没有找到相关文章

最新更新