列中的空值违反非空约束

时间:2012-10-18 13:57:21

标签: sql hibernate postgresql

我在“kladr_full_name”列中有sql错误空值违反了非空约束。

执行请求的数据库中的表:

СREATE TABLE kladr.kladr_name
(
  kladr_code character varying(255) NOT NULL,
  kladr_city_name character varying(121),
  kladr_full_name character varying(487) NOT NULL,
  kladr_index character varying(6),
  kladr_name character varying(100) NOT NULL,
  kladr_naspunkt_name character varying(121),
  kladr_rayon_name character varying(121),
  kladr_region_name character varying(121),
  kladr_socr character varying(20),
  CONSTRAINT kladr_name_pkey PRIMARY KEY (kladr_code )
)
WITH (
  OIDS=FALSE
);
ALTER TABLE kladr.kladr_name
  OWNER TO postgres;

请求db:

    INSERT INTO kladr.kladr_name 
            (kladr_code, 
             kladr_name, 
             kladr_socr, 
             kladr_index, 
             kladr_region_name, 
             kladr_rayon_name, 
             kladr_city_name, 
             kladr_naspunkt_name, 
             kladr_full_name) 
SELECT kladr_code, 
       Upper(kladr_name)                 kladr_name, 
       kladr_socr, 
       kladr_index, 
       (SELECT k1.kladr_socr 
               ||' ' 
               ||k1.kladr_name 
        FROM   kladr.kladr_tmp k1 
        WHERE  k1.kladr_region = k.kladr_region 
               AND k1.kladr_rayon = '000' 
               AND k1.kladr_city = '000' 
               AND k1.kladr_nas_punkt = '000' 
               AND k1.kladr_mod = '00' 
               AND k1.kladr_status = '0')kladr_region_name, 
       (SELECT k1.kladr_socr 
               ||' ' 
               ||k1.kladr_name 
        FROM   kladr.kladr_tmp k1 
        WHERE  k1.kladr_region = k.kladr_region 
               AND k1.kladr_rayon = k.kladr_rayon 
               AND k1.kladr_rayon <> '000' 
               AND k1.kladr_city = '000' 
               AND k1.kladr_nas_punkt = '000' 
               AND k1.kladr_name = '00') kladr_rayon_name, 
       (SELECT k1.kladr_socr 
               ||' ' 
               ||k1.kladr_name 
        FROM   kladr.kladr_tmp k1 
        WHERE  k1.kladr_region = k.kladr_region 
               AND k1.kladr_rayon = k.kladr_rayon 
               AND k1.kladr_city = k.kladr_city 
               AND k1.kladr_city <> '000' 
               AND k1.kladr_nas_punkt = '000' 
               AND k1.kladr_mod = '00')  kladr_city_name, 
       (SELECT k1.kladr_socr 
               ||' ' 
               ||k1.kladr_name 
        FROM   kladr.kladr_tmp k1 
        WHERE  k1.kladr_region = k.kladr_region 
               AND k1.kladr_rayon = k.kladr_rayon 
               AND k1.kladr_city = k.kladr_city 
               AND k1.kladr_nas_punkt = k.kladr_nas_punkt 
               AND k1.kladr_nas_punkt <> '000' 
               AND k1.kladr_mod = '00')  kladr_naspunkt_name, 
       (SELECT k1.kladr_socr 
               ||' ' 
               ||k1.kladr_name 
        FROM   kladr.kladr_tmp k1 
        WHERE  k1.kladr_region = k.kladr_region 
               AND k1.kladr_rayon = '000' 
               AND k1.kladr_city = '000' 
               AND k1.kladr_nas_punkt = '000' 
               AND k1.kladr_mod = '00' 
               AND k1.kladr_status = '0') 
       ||' ' 
       ||(SELECT k1.kladr_socr 
                 ||' ' 
                 ||k1.kladr_name 
          FROM   kladr.kladr_tmp k1 
          WHERE  k1.kladr_region = k.kladr_region 
                 AND k1.kladr_rayon = k.kladr_rayon 
                 AND k1.kladr_rayon <> '000' 
                 AND k1.kladr_city = '000' 
                 AND k1.kladr_nas_punkt = '000' 
                 AND k1.kladr_mod = '00') 
       ||' ' 
       ||(SELECT k1.kladr_socr 
                 ||' ' 
                 ||k1.kladr_name 
          FROM   kladr.kladr_tmp k1 
          WHERE  k1.kladr_region = k.kladr_region 
                 AND k1.kladr_rayon = k.kladr_rayon 
                 AND k1.kladr_city = k.kladr_city 
                 AND k1.kladr_city <> '000' 
                 AND k1.kladr_nas_punkt = '000' 
                 AND k1.kladr_mod = '00') 
       ||' ' 
       ||(SELECT k1.kladr_socr 
                 ||' ' 
                 ||k1.kladr_name 
          FROM   kladr.kladr_tmp k1 
          WHERE  k1.kladr_region = k.kladr_region 
                 AND k1.kladr_rayon = k.kladr_rayon 
                 AND k1.kladr_city = k.kladr_city 
                 AND k1.kladr_nas_punkt = k.kladr_nas_punkt 
                 AND k1.kladr_nas_punkt <> '000' 
                 AND k1.kladr_mod = '00')kladr_full_name 
FROM   kladr.kladr_tmp k 
WHERE  k.kladr_mod = '00' 

DB postgreSql。 jpa prov hibernate。这可能是什么原因?

现在问题是如果修改此查询以在postgres中工作(在oracle db中工作之前),如果某些subquerys返回null?

1 个答案:

答案 0 :(得分:3)

在PostgreSQL中,如果a || b中的任何一个参数为NULL,则NULL形式的表达式将计算为INSERT。因此,如果这些子查询中的任何无法找到记录,则您的NULL语句会尝试将kladr_full_name插入NULL。您需要分别尝试每个子查询,看看哪一个没有给你一个记录(或者给你一个NULL的记录。)


编辑添加以响应OP评论:在Oracle中,没有零长度字符串的概念,因为它们已转换为'' = ''(例如,{{} 1}}不是真的,而'' IS NULL是)。通常转换是单向的 - LENGTH('') IS NULL - 但在||运算符的情况下,它会将NULL转换回零长度字符串,这样'ab' || NULL || 'cd'就是'abcd'。 PostgreSQL不会自动执行此转换,因为它 区分''NULL,但您可以: