1

为了检索我需要的数据,我必须选择没有数据的记录。有些行未填充(?)。

许多这些“未填充”的行都设置有 Not Null 约束。这让事情变得很困难!我不能简单地搜索 NULL 行,因为它们不是 NULL。

我已经能够使用几种方法选择或排除未填充的行。这些方法似乎随机工作或不工作。

示例:选择或排除 st.sart_code 或 st.sart_hold 或 st.sart_status 或 st.sart_date 未填充的记录。

SELECT 
sp.sprite_id, sp.sprite_last, sp.sprite_first,
st.sart_code 
/* 4 data retrieval methods are listed below.  
For st.sart_code, I have substituted:
st.sart_hold, st.sart_status, and st.sart_date in the methods 2-4*/

FROM
sprite sp
JOIN sart st
on sp.sprite_pidm = st.sart_pidm

方法 1 - 选择具有不具有值 EVEA 的行的记录 - st.sart_code 可以包含一个 sp.sprite_id 的多个值。这是一个项目清单。我正在寻找清单中没有 EVEA 的记录

具有 Not Null 约束的 Varchar2 类型

EVEA 不在清单中

WHERE
Sp.sprite_change_ind is null
and
st.sart_pidm NOT IN
(SELECT st.sart_pidm
FROM sart st
WHERE st.sart_code = 'EVEA')

方法 2 - 选择具有不具有值 A2 的行的记录 - st.sart_hold 可以包含一个 sp.sprite_id 的多个值。st.sart_hold 可能是空白/未填充(记录没有保留)或包含几个不同的保留。这些值是帐户保留类型。我正在寻找没有特定“A2”保留的记录。

具有 Not Null 约束的 Varchar2 类型

编辑我刚刚意识到这只有在至少已经有一个持有的情况下才有效。如果此人没有保留,此脚本将不会选择记录(即使此人也没有 A2 保留)。

没有 A2 保留

WHERE
Sp.sprite_change_ind is null
and
group by sp.sprite_id, sp.sprite_last, sp.sprite_first, st.sart_hold
having sum(case when st.sart_hold = 'A2' then 1 else 0 end) = 0;

方法 3 - 选择行中没有 st.sart_status 值的记录——st.sart_status 只能包含 3 个可能值中的 1 个,或者一个 sp.sprite_id 没有值。这些值是文件状态。我正在寻找没有状态的记录

具有 Not Null 约束的 Varchar2 类型

没有状态

WHERE
Sp.sprite_change_ind is null
and
trim(st.sart_status) is null

方法 4 - 选择在 st.sart_date 中不缺少任何值的行的记录(列表中的所有日期字段都已填充)- st.sart_date 可以包含日期,也可以为一个 sp.sprite_id 为空白/未填充。该值是清单项目的接收日期。我排除了没有任何清单项目日期的任何记录(可能有许多项目具有相应的日期)。

具有 Not Null 约束的日期类型

这有点不同,所以我再次包括第一部分。

为相应的清单项目填充所有接收日期

with MYVIEW AS
( 
SELECT 
sp.sprite_id AS Per_ID
sp.sprite_last, 
sp.sprite_first,
st.sart_date as RECEIVED_DATE

FROM
sprite sp
JOIN sart st
on sp.sprite_pidm = st.sart_pidm

WHERE
Sp.sprite_change_ind is null
)

Select 
Per_ID as "ID", 
max(SPRITE_LAST_NAME) as "Last", 
max(SPRITE_FIRST_NAME) as "First",

FROM MYVIEW
GROUP BY Per_ID
HAVING SUM(NVL2(RECEIVED_DATE,0,1)) = 0

我的问题:我很难找到使用 Not Null 约束字段的方法。

编辑:当“非空”约束字段未填充时,我如何查看它的内容?

  1. 为什么在查找未填充的字段时,上述方法并不总是有效?某些方法是否仅适用于某些数据类型(varchar2、数字、日期)?还是与我使用的 JOIN 类型有关?还有什么?

  2. 还有其他方法可以请人指导我吗?任何指导将不胜感激!

  3. “选择存在 [ColumnName DataType() NOT NULL] 的未填充字段的记录”的正确术语是什么?如果我知道我要问的术语,我可以搜索它。

注意我的脚本通常比上面的例子更复杂。我通常至少有 3 个连接和许多 WHERE 子句。

如果这个问题涉及太多,请告诉我!我刚来这地方。:-)

4

1 回答 1

3

可能比答案更长的评论,但因为这里没有太多的活动......

Oracle SQL SELECT 带有“NOT NULL”约束的空白记录Auntie Anita


- 如果它们不为空,你如何有空白 - 这部分是你要问的吗?Alex Poole
- 这是问题之一。 安妮塔阿姨

几件事情要知道:

  1. 在 Oracle 中,空字符串与/''相同NULL。这与区分空字符串和 NULL 字符串的“标准”SQL 不同。VARCHARCHAR
  2. TRIMNULL将 返回NULL/empty strings/space only 字符串。
  3. 由空格/不可见字符组成的字符串不为空。即使它们只包含字符CHR(0) (又名NUL - 只有一个L
  4. 并且 TRIM不会删除不可见的字符。只有空格。

为了说服自己,试试这些:

select NVL2(CAST('' AS VARCHAR2(20)), 'NOT NULL','NULL') FROM DUAL
select NVL2(CAST('' AS CHAR(20)), 'NOT NULL','NULL') FROM DUAL
select NVL2(TRIM('  '), 'NOT NULL','NULL') FROM DUAL
select NVL2(' ', 'NOT NULL','NULL') FROM DUAL
select NVL2(CHR(10), 'NOT NULL','NULL') FROM DUAL
select NVL2(CHR(0), 'NOT NULL','NULL') FROM DUAL
select NVL2(TRIM('  '||CHR(10)), 'NOT NULL','NULL') FROM DUAL
select NVL2(TRIM('  '||CHR(0)), 'NOT NULL','NULL') FROM DUAL

所以,我的猜测是你的“非空字段”实际上包含一些不可见的字符——甚至可能是一个CHR(0). 这是很有可能的,因为在某些语言中,NUL 字符被用作字符串终止符——并且可能在数据导入时因空值/缺失值而潜入您的数据库。有意无意。

要检查这一点,您可能需要尝试RAWTOHEX检查您的可疑数据字段。在下面的示例中,请注意中间NUL 字符在显示为字符串时是如何潜伏而不被注意的。但不在原始十六进制转储中:

SQL> select 'abc' || chr(0) || 'def' AS str, 
           RAWTOHEX('abc' || CHR(0) || 'def') AS hex FROM DUAL


STR                     HEX
abcdef                  61626300646566
^^^^^^                        ^^
Is there something           Yes !
special here?

如果这个问题涉及太多,请告诉我!我刚来这地方。:-)

:D 如果您能够缩小问题范围,“StackOverflow”通常会更有效率。理想情况下提供一些可重现的案例(以前称为SSCCEMCVE)。

花时间仔细检查您的数据,如果需要,请不要犹豫,发布其他更集中的答案。

于 2014-09-26T08:20:04.367 回答