标签: null

正确使用 NULL,并利用业务逻辑与存储过程的 CHECK 约束

这个问题是关于 NULL 的正确使用和对业务逻辑与存储过程的 CHECK 约束的使用。

我有以下表格设置。

实体关系图

我对表进行了标准化以避免使用 NULL。问题是这些表中的一些由于业务流程而相互依赖。有些设备必须经过消毒,有些设备在另一个系统中进行跟踪。所有设备最终都将在处置表中处置。

问题是我需要执行检查,例如如果布尔字段RequiresSantization为真,则在DisposalDate输入Sanitize字段之前无法输入。

此外,如果布尔值为IsTrackedInOther真,则OfficialOutOfService必须先输入字段,然后DisposalDate才能输入。

如果我将所有这些列合并到Archive.Device表中,那么我将拥有 NULL 字段,但我将能够使用 CHECK 约束管理所有业务规则。

另一种方法是让表保持原样,并通过从表中选择以检查记录是否存在,然后抛出适当的错误来管理存储过程中的业务逻辑。

这是可以适当使用 NULL 的情况吗?布尔领域IsTrackedInOtherRequiresSanitization基本赋予意义的NULL字段。如果IsTrackedInOther是,false则设备未在其他系统中跟踪SectionID并且SpecialDeviceCode为 NULL,我知道它们应该为 NULL,因为它未在其他系统中跟踪。同样,OfficialOutOfServiceDateOOSLogPath我知道会是NULL藏汉,并且DisposalDate可以随时进入。

如果IsTrackedInOthertrue,那么SectionIDSpecialDeviceCode将是必需的,如果OfficialOutOfServiceDateOOSLogPath是NULL,那么我知道它们还没有被正式从该系统中删除,因此DisposalDate在输入它们之前不能有a 。

所以这是一个问题

单独的表/无 NULL/在存储过程中强制执行规则

对比

在 CHECK 约束中组合表/NULLs/强制规则。

我知道在图片中使用 NULL …

null database-design constraint stored-procedures

2
推荐指数
1
解决办法
473
查看次数

MySql Order by isnull() 性能问题

我下面的 sql 用于列出 10 天前添加的股票。Order by isnull(Price) 被使用,这样没有任何价格的股票仍然会被列出。

AddDate 和 Price 有一个索引。

SELECT Id, Price FROM tblStock
where AddDate >= date_sub(curdate(),interval 10 day)
order by isnull(Price), Price asc limit 50
Run Code Online (Sandbox Code Playgroud)

解释 sql 显示它没有使用价格指数。所以我试图改进查询并提出了以下 sql

SELECT Id, Price FROM tblStock
where AddDate >= date_sub(curdate(),interval 10 day)
and Price is not null
order by Price asc limit 50
Run Code Online (Sandbox Code Playgroud)

新的 sql 运行得更快,并且解释显示它使用价格索引,但问题是永远不会选择具有空值的价格。

寻找有关如何解决此问题的任何意见或建议。谢谢。

mysql performance index null order-by

2
推荐指数
1
解决办法
4674
查看次数

SQL Server 2012 中不同的子句如何处理 Null/Unknow?

(SQL 和 SQL Server 相对较新)我正在阅读Itzik Ben-Gan 的SQL Server 2012 T-SQL Fundamentals。奥托尔指出:

SQL 在不同的语言元素中对 UNKNOWN 有不同的处理方式

所以,我浏览了 SQL Server 文档,特别是WHEREclause,但找不到任何关于如何NULL/UNKNOWN处理的具体信息。

有人可以指出我正确的文档或指出我在文档中读错的内容吗?(我高度怀疑我的问题的答案深藏在 SQL 标准的某个地方,但对我来说可能太复杂了,至少在这一点上。)

null sql-server

2
推荐指数
1
解决办法
1239
查看次数

INSERT 不适用于 NOT NULL 但 UPDATE 可以,为什么?

我有这个表定义:

CREATE TABLE `media` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `brands_id` int(11) DEFAULT NULL,
  `media_type` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL,
  `title` varchar(45) COLLATE utf8_unicode_ci NOT NULL,
  `description` longtext COLLATE utf8_unicode_ci NOT NULL,
  `thumbnail_url` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `media_url` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `media_code` varchar(45) COLLATE utf8_unicode_ci NOT NULL,
  `inactive` tinyint(1) NOT NULL,
  `createdAt` datetime NOT NULL,
  `updatedAt` datetime NOT NULL,
  `titleHtml` varchar(45) COLLATE utf8_unicode_ci NOT NULL,
  `descriptionHtml` longtext COLLATE utf8_unicode_ci NOT NULL,
  `useHtml` tinyint(1) NOT NULL,
  PRIMARY KEY …
Run Code Online (Sandbox Code Playgroud)

mariadb null insert update

2
推荐指数
1
解决办法
1485
查看次数

NULL 时的计算字段

我的表中有两个字段:A int, B int。我想添加两个使用这两个字段& 的计算字段 ( CF1& CF2) 。AB

CF1 = (case when [A]>[B] then (CF1=3) else case when [A]<[B] then (CF1=0) else (CF1=1) end end)

CF2 = (case when [A]<[B] then (CF2=3) else case when [A]>[B] then (CF2=0) else (CF2=1) end end)
Run Code Online (Sandbox Code Playgroud)

这工作正常,但是当两个字段 ( A& B) 是NULL,CF1并且CF2是 = 1 时。如何避免这种情况?我的意思是,当领域中的任意一个A或者BNULL,无论CF1CF2也应该是NULL

换句话说:应该只有在0,1或3的值CF1和 …

null sql-server t-sql computed-column

2
推荐指数
2
解决办法
787
查看次数

用于存储用户配置文件的可空列或 jsonb?

我决定使用可为空字段或 jsonb 来存储用户配置文件。最初,这将用于联系人:emailphone。我预计稍后可能会添加其他列,例如mobilewebsite。此外,可能还有其他不相关的字段,例如设置/首选项、保存的搜索等。

我已经决定我不想为此使用任何形式的键值存储(或任何涉及多对多关系的模式),除非有非常好的理由。

jsonb 的优点:

  • 如有必要,可以为每个“列”存储多个值
  • 添加新字段只需要 JS 编码和文档

jsonb 的缺点:

  • 将“列”名称存储为每个“行”的字符串的开销
  • Wonky 执行比较查询(我认为我的使用场景不适用)
  • 不得不期待意外

还有什么要添加到这个优点/缺点列表中的吗?尽管我只想使用可为空的列,但我认为忽略 jsonb 是一种疏忽 - 这似乎是一个令人信服的选择。

schema postgresql null database-design json

2
推荐指数
1
解决办法
870
查看次数

在什么情况下,间隙和岛屿需要计数(x 或空)?

这个答案中,Erwin Brandstetter 说:

count(step OR NULL) OVER (ORDER BY date)是最短的语法,也适用于 Postgres 9.3 或更早版本。count()只计算非空值。在现代 Postgres 中,更简洁、等效的语法是:

count(step) FILTER (WHERE step) OVER (ORDER BY date)
Run Code Online (Sandbox Code Playgroud)

我不确定为什么count(step OR NULL)是首选。在我的查询中,我执行以下操作。我重命名了我的变量以匹配他的同时保持语法。

CASE WHEN lag(id_type) OVER (ORDER BY date) <> id_type THEN 1 END AS step
Run Code Online (Sandbox Code Playgroud)

我们正在计算它返回的值。请注意,case 只能返回 1 或 null。

  • 如果两者不相等,则返回 1。
  • 如果它们相等,则返回不计算在内的 null。

欧文的回答是:

这假设涉及的列是NOT NULL. 否则你需要做更多。

所以我更迷茫了。添加count(step OR NULL)什么来保护我们的查询有什么意义?

任何人都可以分解这一点,也许可以展示两个带有数据的示例,其中只有一个 - 一个 -count(x OR NULL)有效?

postgresql null count window-functions gaps-and-islands

2
推荐指数
2
解决办法
842
查看次数

从每一列中选择最大值,即使其中一个值为空

我有一张road_age_test桌子:

create table road_age_test (
    surface_year int,
    base_year int
);

insert into road_age_test (surface_year, base_year) values (10,20);
insert into road_age_test (surface_year, base_year) values (30,null);
insert into road_age_test (surface_year, base_year) values (null,40);
insert into road_age_test (surface_year, base_year) values (null,null);
insert into road_age_test (surface_year, base_year) values (50,50);

commit;

select * from road_age_test;

SURFACE_YEAR  BASE_YEAR
------------ ----------
          10         20
          30       null    
        null         40
        null       null
          50         50
Run Code Online (Sandbox Code Playgroud)

我想从每一列中选择最大值,即使其中一个值为空:

GREATEST_YEAR
-------------
           20
           30
           40
         null
           50
Run Code Online (Sandbox Code Playgroud)

什么是最简单的方法来做到这一点?


注意:如果两个值都是null,我想返回null, …

null oracle select oracle-12c

2
推荐指数
1
解决办法
104
查看次数

文本和 NULL 值的连接如何返回非空结果?

断言 1

连接运算符||可以连接任何字符串类型的值,返回text. 在 Postgres 中,每种类型都有一个文本表示并且可以转换为text. 因此,引用手册

但是,字符串连接运算符 ( ||) 仍然接受非字符串输入,只要至少一个输入是字符串类型

有关的:

断言 2

连接一个或多个NULL值产生结果NULL

test=# SELECT (text 'foo' || NULL) IS NULL
test-#      , (text 'bar' || char '1' || NULL ) IS NULL
test-#      , (NULL::bigint || text 'baz') IS NULL;
 ?column? | ?column? | ?column? 
----------+----------+----------
 t        | t        | t
Run Code Online (Sandbox Code Playgroud)

是否可以连接 atext和 aNULL值并获得非空结果?

换句话说, …

postgresql null concat

2
推荐指数
1
解决办法
1171
查看次数

为什么我的非空列在我的 CTE 递归查询中变得可以为空?

我有一个简单的分层表。假设它有这些列:

Id, [Guid], ParentId, Title
Run Code Online (Sandbox Code Playgroud)

只有可以ParentId为空。其他列不可为空。

我创建了一个递归查询来显示从节点到根的路径。为此,我使用了 CTE。这是我的查询:

with Anchor (Id, [Guid], ParentId, Title, [Path])
as
(
    select Id, [Guid], ParentId, Title, cast('' as nvarchar(100)) as [Path]
    from Hierarchies
    where ParentId is null
    union all
    select Hierarchies.Id, Hierarchies.[Guid], Hierarchies.ParentId, Hierarchies.Title, cast(Anchor.[Path] + '/' + Hierarchies.Title as nvarchar(100)) as [Path]
    from Hierarchies
    inner join Anchor
    on Hierarchies.ParentId = Anchor.Id
)
select 
    isnull(Anchor.Id, 0) as Id,
    isnull(Anchor.[Guid], newid()) as [Guid],
    Anchor.ParentId,
    Anchor.Title,
    Anchor.[Path]
from Anchor
Run Code Online (Sandbox Code Playgroud)

问题是,当我将此查询转换为视图时,该Guid列变为可以为空。我什至使用isnull()函数来强制它不为空。令我惊讶的是,这 …

null sql-server cte recursive

2
推荐指数
1
解决办法
69
查看次数