每个开发人员都需要了解的一个 SQL 技巧

发布于 2024-07-18 06:45:29 字数 2168 浏览 21 评论 0

对于数据过滤而言 CHECK 约束已经算是相当不错了。然而它仍存在一些缺陷,比如说它们是应用到表上面的,但有的时候你可能希望指定一条约束,而它只在特定条件下才生效。

使用 SQL 标准的 WITH CHECK OPTION 子句就能完成这点,至少 Oracle 和 SQL Server 都实现了这个功能。下面是实现方式:

CREATE TABLE books (
  id    NUMBER(10)         NOT NULL,
  title VARCHAR2(100 CHAR) NOT NULL,
  price NUMBER(10, 2)      NOT NULL,
   
  CONSTRAINT pk_book PRIMARY KEY (id)
);
/
 
CREATE VIEW expensive_books
AS
SELECT id, title, price
FROM books
WHERE price > 100
WITH CHECK OPTION;
/
 
INSERT INTO books 
VALUES (1, '1984', 35.90);
 
INSERT INTO books 
VALUES (
  2, 
  'The Answer to Life, the Universe, and Everything',
  999.90
);

正如你看到的那样,expensive_books 是那些价格大于 100 块的书。这个视图只会返回第二本书:

SELECT * FROM expensive_books;

上述查询的输出是:

ID TITLE                                       PRICE
-- ----------------------------------------- -------
 2 The Answer to Life, the Universe, and ...   999.9 

不过由于我们使用了 CHECK OPTION,我们还能防止用户往"昂贵的书籍"中插入那些廉价的。比如说,我们运行下这个查询:

INSERT INTO expensive_books 
VALUES (3, '10 Reasons why jOOQ is Awesome', 9.99);

它是无法生效的。你会看到:

ORA-01402: view WITH CHECK OPTION where-clause violation

我们也无法将贵的书更新成便宜的:

UPDATE expensive_books
SET price = 9.99;

这个查询也会报出同样的 ORA-01402 错误。

WITH CHECK OPTION 内联

如果你需要局部防止脏数据被插入到表中,你可以使用 WITH CHECK OPTION 的内联子句:

INSERT INTO (
  SELECT *
  FROM expensive_books
  WHERE price > 1000
  WITH CHECK OPTION
) really_expensive_books
VALUES (3, 'Modern Enterprise Software', 999.99);

上述查询同样也会导到 ORA-01402 错误。

使用 SQL 转换来生成特殊约束

CHECK OPTION 对于已存储的视图非常有用,它使得那些无权直接访问底层表的用户能够获得正确的授权,而内联的 CHECK OPTION 主要是在应用的 SQL 中间转换层来进行动态 SQL 的转换。

这个可以通过 jOOQ 的 SQL 转换功能 来完成,比如说,你可以在 SQL 语句中对某个表进行约束,从根本上阻止了非法 DML 的执行。如果你的数据库没有本地提供行级别的安全性的话,这也是一个实现多租户的不错的方式。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

清眉祭

暂无简介

文章
评论
26 人气
更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文