标签: postgresql

在 JDBC 中禁用显式提交,在 SQL 中检测它们,或将数据库置于只读状态

背景:我在http://sqlfiddle.com 上工作(我的网站)上工作,并试图防止那里可能出现的一种滥用途径。我希望通过询问我目前正在解决的问题,我不会无意中使潜在的虐待变得更糟,但是你能做什么?我相信你们。

我想阻止任何用户在给定的事务块内发出显式的“提交”调用。从 SQL Fiddle 的上下文来看,事务块是在右侧面板上执行的代码。基本上,我正在循环执行一个纯文本 SQL 命令列表,并且我想确保它们所做的所有更改都将在批处理结束时回滚。通常,他们的更改会回滚,但有时文本中会有明确的“提交”语句,因此我的回滚当然不起作用。这种显式提交很可能来自用户试图破坏 SQL Fiddle 上的架构,因此其他人会看到错误。

主要期望结果:如果可能,我想在 JDBC 级别禁用显式提交。这是因为我要支持多个数据库后端供应商,当然每个供应商在低级别都有自己的怪癖。

回退选项:如果无法将 JDBC 配置为禁用显式提交,那么我愿意接受在为以下每个后端处理批处理时检测显式提交的解决方案:SQL Server、Oracle、MySQL 和 PostgreSQL。

对于 SQL Server,我想到了这个解决方案:在我执行它之前解析语句的 XML 查询计划,并检查是否存在与此 XPath 匹配的条目:

//*[@StatementType="COMMIT TRANSACTION"]
Run Code Online (Sandbox Code Playgroud)

我认为这对 SQL Server 非常有效。但是,这种方法不适用于其他数据库类型。Oracle 用于显式提交的 XML 执行计划输出并未提及您正在运行提交语句这一事实(而是简单地重复它提交的查询的执行计划输出)。PostgreSQL 和 MySQL 根本不为显式提交提供任何执行计划输出(XML 或其他)。

这让我需要检查“提交”一词的实际语句。这会起作用,除非可能有各种变化:

declare @sql varchar(50)
set @sql = 'com' + 'mit'
exec(@sql);
Run Code Online (Sandbox Code Playgroud)

上面是 SQL Server 的一个例子(我可以解决),但我猜想类似的事情对于 Oracle、MySQL 和 PostgreSQL 也是可能的。我在这个假设上错了吗?也许他们不允许“动态”提交语句?随意使用 SQL Fiddle(最好不是示例模式或其他人可能正在使用的模式)来查看是否可以在 Oracle、MySQL 和 PostgreSQL 中进行类似的操作。如果没有,也许简单的字符串检测可能适用于那些。

还有一种可能

我想到了另一个选择 - 如果您知道一种将这些数据库中的任何一个设置为只读模式的方法,例如在该模式下无法提交任何内容,那也可以。我仍然需要允许启动事务并在其中运行代码,只要在该模式下不能提交任何内容。那可能吗?

更新

我最近学到的 - 这实际上不是 PostgreSQL …

mysql postgresql oracle jdbc transaction

12
推荐指数
1
解决办法
1716
查看次数

如何使用默认值随机字符串在数据库中创建列

我可以在 DB 表 (PostgreSQL) 中创建具有默认值随机字符串的列,以及如何创建?

如果不可能,请告诉我。

postgresql random default-value

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

将串行列添加到大表的最有效方法

将 BIGSERIAL 列添加到大表(约 3 Bil. 行,约 174Gb)的最快方法是什么?

编辑:

  • 我希望该列是现有行 ( NOT NULL) 的递增值。
  • 我没有设置填充因子(回想起来,这似乎是一个错误的决定)。
  • 我对磁盘空间没有问题,只是希望它尽可能快。

postgresql performance sequence update

12
推荐指数
1
解决办法
3万
查看次数

在 PostgreSQL 上连续 7 天计算滚动总和

我需要为每行(每天 1 行)获取 7 天的滚动总和。

例如:

| Date       | Count | 7-Day Rolling Sum |
------------------------------------------
| 2016-02-01 | 1     | 1
| 2016-02-02 | 1     | 2
| 2016-02-03 | 2     | 4
| 2016-02-04 | 2     | 6
| 2016-02-05 | 2     | 8
| 2016-02-06 | 2     | 10
| 2016-02-07 | 2     | 12
| 2016-02-08 | 2     | 13 --> here we start summing from 02-02
| 2016-02-09 | 2     | 14 --> here we …
Run Code Online (Sandbox Code Playgroud)

postgresql aggregate window-functions postgresql-9.4

12
推荐指数
1
解决办法
3万
查看次数

在针对另一台机器的 pg_dump 期间创建“pg_catalog.tablename”的权限被拒绝

我正在尝试将一些表从 9.5 beta 2 转储到 9.4.4 服务器。我使用的命令的形式是相当标准的:

pg_dump -t table dbname | psql -h hostname -d dbname
Run Code Online (Sandbox Code Playgroud)

我正在使用 Postgres 用户,我意识到这可能并不理想,但因为它们都是我只使用的开发数据处理框,并且与随后的错误相关。最初,我得到了错误

错误:无法识别的配置参数“row_security”

这是预期的,因为此功能是 9.5 中的新功能,是的,我意识到不建议在不同的 Postgres 版本之间使用 pg_dump,但是,遗憾的是,这是不可避免的,因为我遇到了一个非常模糊的错误,并且需要移动一个大的一次静态数据量。

因此,使用这个可怕的 hack 来删除 row_security 错误,并在第一个错误时打开停止:

pg_dump -t tablemame dbname |sed 's/SET row_security = off;//'|
psql -v ON_ERROR_STOP=1 -h hostname -d dbname
Run Code Online (Sandbox Code Playgroud)

我现在得到:

错误:权限被拒绝创建“pg_catalog.tablename”详细信息:当前不允许修改系统目录

虽然使用 Postgres 用户/角色可能是不可取的,但我的理解是不应该有这种性质的许可问题。我对任何建议持开放态度,因为这是一次性操作,并且这些是未连接到任何实时服务的数据处理开发箱,因此权宜之计优于理想的公司数据访问策略。话虽如此,最好了解如何正确执行此操作并在将来避免这种情况。

postgresql postgresql-9.4 postgresql-9.5

12
推荐指数
1
解决办法
6761
查看次数

将 Postgres TIMESTAMP 转换为 TIMESTAMPTZ

我有一个在 Postgres 上运行的大小合适(约 50k 行)的时间序列数据库,还有一些其他结构化数据(在另一个数据库实例中)要小得多。

愚蠢的是,当我最初设计这个东西时,我把所有的字段都作为TIMESTAMP WITHOUT TIME ZONE,现在我用恼人的时区相关的错误来支付它。我希望一切都是明确的,所以想将字段转换为TIMESTAMP WITH TIME ZONE. 我意识到这不会存储额外的信息,并且我所有的时间戳都已经在 UTC 中,所以迁移应该是微不足道的,但我想知道是否有任何复杂的事情/潜在的绊倒块会证明有问题(这是一个生产客户依赖它的数据库)?

postgresql migration datatypes timezone

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

用一个查询插入多个表

我想通过一个查询将数据添加到至少三个表中。我想到了这样的事情:

WITH ins AS (
  INSERT INTO core.adr
    (street, "number", postal_code, city)
  VALUES
    ('test 1', '25a', '00912', 'villageman')
  RETURNING id)
INSERT INTO core.adr_information
  (idref, info)
SELECT id, 'test data'
FROM ins;
Run Code Online (Sandbox Code Playgroud)

这完全适用于两个表。

这里的主要问题是,所有其他查询都需要id第一个INSERT查询的值,这似乎无法通过这种方式进行管理。我认为它可以通过存储过程或事务轻松完成,但我希望解决方案是一个简单而可靠的查询。

我是否忽略了什么?是否有可能以这种方式或另一种方式(没有存储过程*或事务)?


笔记

* Altough,严格来说,Postgres没有存储过程,只有功能,@Erwin Brandstetter修改正确地通过评论中指出。有关相关信息,请参阅本系列帖子

postgresql cte

12
推荐指数
1
解决办法
6万
查看次数

如果更新后整行保持不变,如何签入触发器?

当然,我可以像这样对每一列进行比较:

if (old.column1 = new.column1 and old.column2 = new.column2...)
Run Code Online (Sandbox Code Playgroud)

但是,例如,如果我将来添加另一列,它将是硬编码的并且难以维护。

有没有办法检查所有列是否保持不变而无需手动检查每个单独的列?

postgresql trigger

12
推荐指数
1
解决办法
2983
查看次数

pgAdmin 4, 没有内置的 SSH 隧道配置?

第一次尝试使用 pgAdmin 4。
看起来没有用于连接的内置 SSH 隧道配置。
我搜索了文档,但没有提到该功能。

它永远消失了吗?

postgresql pgadmin

12
推荐指数
1
解决办法
1万
查看次数

postgresql 中存储的用户名和密码在哪里?

我正在使用 PostgreSQL 数据库。我在其中创建用户。所以我想知道

  1. 用户名和密码存储在哪里?
  2. 密码是存储为纯文本还是加密数据?
  3. root 用户是否能够读取密码?

postgresql logins

12
推荐指数
1
解决办法
6万
查看次数