Postgres 9.3 Debian 7.0
我为特定用户创建了特定模式,并在此模式中为该用户创建了一个视图,因此这是他知道存在的唯一表。问题是这个用户需要使用这个表的主键的序列,但它说“错误:序列的权限被拒绝”
原始表及其序列属于模式 A。此用户的模式 B 具有此表 T 的可插入视图。我不能为该用户授予模式 A 的使用权,否则他将能够看到所有的名称和定义我的桌子。
问题是:有没有办法为这个序列创建某种视图,以便他可以调用 nextval() 和 currval()?目标是使该序列可用于该受限用户,而无需让他访问该序列实际所属的主模式。
我创建了一个table_cleanedliketable并从tableinto插入了唯一值table_cleaned。现在我想更换table与table_cleaned使用
DROP TABLE table;
ALTER TABLE table_cleaned rename to table;
Run Code Online (Sandbox Code Playgroud)
但第一条语句给出了cannot drop table cals_status because other objects depend on it.
我绝对不想使用,cascade因为它会删除所有相关行。
我怎样才能安全地用干净的副本替换旧表?
按照 Erwin Brandstetter 的建议,这是错误消息的缺失细节:
Run Code Online (Sandbox Code Playgroud)DETAIL: default value for column id of table cals_status_deduplicated depends on sequence cals_status_id_seq
在 Oracle 序列的上下文中,当持久化 > 2 亿条记录时,如果序列缓存是默认值,是否会对数据库产生性能影响10000?也就是说,1,000,000在将使用 > 2 亿个序列的事务期间,将此值修改为周围的值是否会给我带来任何好处?
我已经啮合在一起的方式来确定什么data_type是在data_type创建基于掀起了新表时,你的语法使用PostgreSQL的维基页面。
如果我的查询有问题,我需要真正知道在给定场景中什么会在显式上下文中抛出它在纯粹的测试数据库/表上运行一个或多个查询以修改该数据库/表,所以运行这个查询以测试任何误报。
SELECT pg_attribute.attname,
format_type(pg_attribute.atttypid, pg_attribute.atttypmod),
CASE
WHEN format_type(pg_attribute.atttypid, pg_attribute.atttypmod)='bigint' THEN 'bigserial'
WHEN format_type(pg_attribute.atttypid, pg_attribute.atttypmod)='integer' THEN 'serial'
END AS type
FROM pg_index, pg_class, pg_attribute
WHERE pg_class.oid = 'delete2'::regclass
AND indrelid = pg_class.oid
AND pg_attribute.attrelid = pg_class.oid
AND pg_attribute.attnum = any(pg_index.indkey)
AND indisprimary;
Run Code Online (Sandbox Code Playgroud)
这是一个带有主键的表,该表不使用此查询返回主键:
CREATE TABLE delete_key_bigserial (
test1 integer,
id bigserial NOT NULL,
col1 text,
col2 text,
test2 integer
);
Run Code Online (Sandbox Code Playgroud) 鉴于以下代码:
CREATE SEQUENCE dbo.NextTestId AS [bigint]
START WITH 10 INCREMENT BY 2 NO CACHE
GO
DECLARE
@variableNumberOfIdsNeeded INT = 7, -- This will change for each call
@FirstSeqNum SQL_VARIANT , @LastSeqNum sql_variant, @SeqIncr sql_variant;
EXEC sys.sp_sequence_get_range @sequence_name = N'dbo.NextTestId',
@range_size = @variableNumberOfIdsNeeded,
@range_first_value = @FirstSeqNum OUTPUT,
@range_last_value = @LastSeqNum OUTPUT,
@sequence_increment = @SeqIncr OUTPUT;
-- The following statement returns the output values
SELECT @FirstSeqNum AS FirstVal, @LastSeqNum AS LastVal, @SeqIncr AS SeqIncrement;
Run Code Online (Sandbox Code Playgroud)
我得到这样的结果:
FirstVal LastVal SeqIncrement
------- ------- --------------
38 …Run Code Online (Sandbox Code Playgroud) sql-server sequence sql-server-2012 cross-apply number-table
观察:我在 PostgreSQL 实例中的一个表上有一个串行索引,并且我执行了一个将新记录插入到该表中的函数。函数失败(原因不重要),事务被回滚......但索引增加并且没有回滚。这会导致未使用的序列值,例如具有索引 1、2、4、5、7 等且没有删除的表。
问题:有什么办法可以回收丢失的序列值,或者防止失败的函数增加索引?
我知道有其他方法可以缓解这个潜在问题,但我仍然很好奇。
我正在尝试使用相同的键字段对多个表执行 INSERT。根据序列操作函数:
重要提示:由于序列是非事务性的,如果事务回滚,则 setval 所做的更改不会撤消。
以上让我担心在我的交易过程中其他东西可能会更新序列。
所以这是我当前的查询:
BEGIN;
--[other queries and stuff here]
CREATE TEMPORARY TABLE my_temp_table ON COMMIT DROP AS
SELECT
(SETVAL('seq_A',(SELECT "last_value" FROM seq_A) + COUNT(*) OVER ()) - (ROW_NUMBER() OVER (ORDER BY some_other_table.field1 DESC))) AS primarykeyid,
some_other_table.morefields
FROM
some_other_table;
--[INSERTs into multiple different tables with primarykeyid here]
COMMIT;
Run Code Online (Sandbox Code Playgroud)
是否SETVAL被调用一次中的每一行my_temp_table或者它被调用一次?
在创建之前进行单独的查询以my_temp_table在运行之前“保留”值会更好吗?例如:
BEGIN;
--[other queries and stuff here]
CREATE TEMPORARY TABLE my_temp_sequence_value ON COMMIT DROP AS
SELECT
(SETVAL('seq_A',(SELECT "last_value" FROM seq_A) …Run Code Online (Sandbox Code Playgroud) 文档中指出:
仅当记录完全填充后才会发生重复验证。在某些情况下,这可能会导致在创建过程中将同一个编号用于多个记录,但随后会被识别为重复项
我不想在像这样的插入查询中使用该数字:
INSERT Test.Orders (OrderID, Name, Qty)
VALUES (NEXT VALUE FOR Test.CountBy1, 'Tire', 2) ;
Run Code Online (Sandbox Code Playgroud)
我想在我的网络应用程序中获取该数字并使用它来构造密文。并将加密后的代码存储在数据库中。因此,就我而言,插入时没有重复检查。
我需要知道的是,两个客户端是否有可能NEXT VALUE FOR几乎同时调用函数并获得相同的值?或不?(我需要不要发生这种情况)
在 Postgres 10 中创建序列时,如何在更新时自动递增?(不仅仅是为下一个插入的行分配下一个更高的数字。)
例如,假设我创建了在此页面上找到的下表和序列:
CREATE TABLE fruits(
id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL
);
INSERT INTO fruits(name) VALUES('Orange');
INSERT INTO fruits(id,name) VALUES(DEFAULT,'Apple');
SELECT * FROM fruits;
id | name
----+--------
1 | Apple
2 | Orange
(2 rows)
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,它在插入时正确地自动将“id”列加一。但是,如果我进行如下更新:
update fruits
set name = 'Orange2'
where name = 'Orange';
SELECT * FROM fruits;
id | name
----+--------
1 | Apple
How do I get this to auto-increment to 3? --> 2 | Orange2
(2 …Run Code Online (Sandbox Code Playgroud) sequence ×10
postgresql ×6
oracle ×2
sql-server ×2
catalogs ×1
concurrency ×1
cross-apply ×1
datatypes ×1
ddl ×1
dependencies ×1
functions ×1
index ×1
number-table ×1
performance ×1
permissions ×1
primary-key ×1
schema ×1