WITH 上的PostgreSQL 文档显示了以下示例:
WITH regional_sales AS (
SELECT region, SUM(amount) AS total_sales
FROM orders
GROUP BY region
), top_regions AS (
SELECT region
FROM regional_sales
WHERE total_sales > (SELECT SUM(total_sales)/10 FROM regional_sales)
)
SELECT region,
product,
SUM(quantity) AS product_units,
SUM(amount) AS product_sales
FROM orders
WHERE region IN (SELECT region FROM top_regions)
GROUP BY region, product;
Run Code Online (Sandbox Code Playgroud)
它还指出:
WITH 查询的一个有用特性是,它们在每次执行父查询时仅被评估一次,即使它们被父查询或同级 WITH 查询多次引用。
我看到它WITH
可以用于其他事情,比如递归评估。但是在上面的例子中,使用WITH
和创建临时表有什么重要的区别吗?
在我正在处理的应用程序中,我们有一种“受限制的一对多”关系。我想知道这是否有名称,以及是否可以在数据库级别强制执行。
标准的一对多可能是people
to pets
。一个人可以养多只宠物,每只宠物都属于指定的物种。你可以有 0 只宠物,或者 2 只狗和一只猫,或者只有一只长尾小鹦鹉等等。
在我们的例子中,我们想说“一个人可以有很多宠物,但每种宠物不能超过一只”。你可以拥有 0 只宠物,或者只有一只猫,或者一只狗和一只长尾小鹦鹉,但你永远不能拥有 2 个任何物种。
我只能看到两种方法来做到这一点:
people
为每个可能的宠物的外键(acat_id
和 adog_id
等)设置一列。不过,这意味着NULL
桌子上会有很多s。pets
都有一个指向 的外键people
,并使用数据库外部的代码按物种强制执行唯一性。任何替代想法?
是否可以将 aDELETE
作为 a 的子查询运行SELECT
?例如:
SELECT * FROM posts where title = (DELETE FROM posts returning 'whoops');
Run Code Online (Sandbox Code Playgroud)
当我尝试这个时,我得到syntax error at or near "FROM"
,指向FROM
的DELETE
,所以这似乎不可能,但也许我只是以某种方式做错了。
上下文:我试图了解某些 SQL 注入攻击可能造成的损害。在这种情况下,整个查询将在没有变量绑定的准备好的语句中运行。这意味着攻击者无法运行多个顶级语句,但我正在尝试评估子查询可能造成的损害。
编辑:我应该说,查询代码正在做类似的事情:
query_parameter = blindly_read_from_user_input()
# this is just interpolated into a string
db_query = "SELECT * FROM posts WHERE title = '#{query_parameter}'"
connection.prepare("query_name", db_query)
connection.exec_prepared("query_name")
Run Code Online (Sandbox Code Playgroud)
所以:
我正在尝试查看是否可以在此现有查询结构中基于 SQL 注入删除记录。
索引需要多少来缩小搜索结果的范围才能有助于加快查询速度?
整个范围内的一些示例:
我认为索引的目标是快速将搜索范围缩小到几行,因此,最后一种情况最好,第二种情况可以,第一种情况无用。
我对么?如果是这样,大致有用的线在哪里?例如,如果一个索引可以将结果缩小到 1% 的行,那有用吗?10% 还是 25% 呢?
我正在使用 PostgreSQL 9.6。
我有一个物化视图来支持跨两个表的全文搜索,我将其称为posts
和tags
。这些表格很少更新和频繁搜索。
我试图找到一个好的策略来运行REFRESH MATERIALIZED VIEW post_search
.
理想的解决方案会是这样的触发器:在任何交易修饰的(或之后)的端部posts
,tags
和/或posts_tags
(连接表),刷新物化视图正好一次。
我怎么能做到这一点?
本文指出 MySQL 存在以下安全问题:
USERS
id | email | password_reset_token
1 | one@example.com | QTlXww)uV!Hdg3U6aGwKV2FPvAqzVgPx
2 | two@example.com | CZor5t7WbX#LTeqiG3v@6f3@z#)BfK*n
Run Code Online (Sandbox Code Playgroud)
在这里,我们有很好的随机令牌,用户必须证明他们拥有才能重置他们的帐户。但是用户设法提交了一个重置令牌0
,所以我们运行这个查询:
SELECT * FROM `users` WHERE `email` = 'one@example.com' AND `password_reset_token` = 0
Run Code Online (Sandbox Code Playgroud)
MySQL将令牌转换VARCHAR
为 anINT
以进行比较。它认为一个VARCHAR
不以数字开头的 a等于 0。因此,攻击者可以匹配任何非数字字符串并接管帐户。
即使重置令牌开始一些数字,情况也好不到哪里去。MySQL 在进行此比较时忽略除初始数字之外的所有字符,因此它考虑12blahblah3blah4
等于12
,这使得猜测更容易。
我可以将 MySQL 配置为不进行这种类型转换吗?例如,如果它投射INT
到VARCHAR
而不是反之,则此攻击将不起作用。
如果使用'0'
而不是运行查询0
,这将不起作用。本文根据 Ruby on Rails 对 XML 的接受程度来讨论此漏洞,其中type=integer
属性说服 Rails 在查询中发送一个实际整数。
该错误已在 …