对检查表的记录上次更新、修改或删除时间的一些研究使我找到了称为 ora_rowscn 的伪列。
首先,我这样做:
select max(ora_rowscn) from tablename;
我记下了这个数字。然后我执行插入、更新和删除,检查每个之前和之后的最大值。它似乎随着每种类型的变化而增加。
如果您想知道我为什么要这样做,我们会在 C# windows 服务中缓存实体列表。此服务在两个负载平衡的服务器上运行,因此每个服务器都有一个单独的实例运行。当服务器 A 上发生更新时,服务器 B 需要知道它。我想要做的是将 max(ora_rowscn) 缓存到一个变量中。每次我们的应用程序插入、更新或删除一条记录时,它都会从数据库中获得一个新的最大值。如果值不同,那么它显然知道它需要从数据库中获取一个新列表。
所以我的实际问题是:是否还有其他我应该注意的问题可能会导致插入、更新或删除记录而不增加该值?
编辑:有人可以添加ora_rowscn为标签吗?
我想做这个
INSERT INTO AdminAccounts (Name)
SELECT Name
FROM Matrix
Run Code Online (Sandbox Code Playgroud)
但我不想创建重复项。即,我几周前运行了它并且需要更新数据。
我们有几个由作业调用的存储过程,它们遵循特定的模式(旨在最小化阻塞)。其中一些 proc 有时会挂起,运行 CPU、tempdb 分配、读取和写入,直到被终止。图案是:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
CREATE #RemoteTemp...;
INSERT INTO #RemoteTemp EXEC MyLinkedServer.DbName.SchemaName.ProcName;
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
SELECT...INTO #MixedTemp FROM #RemoteTemp JOIN LocalTable...;
Run Code Online (Sandbox Code Playgroud)
然后我们使用#MixedTemp. 但是,最后一条语句有时会在不到一秒的时间内运行,有时会挂起,即使每次执行的行数都相同。什么可能导致这种情况?
附加信息:
挂起期间:
Sch-S 锁定本地表。在正在读取的临时表上:
Lock resource_type="HOBT.BULK_OPERATION" request_mode="S"
request_status="GRANT" request_count="1" Lock resource_type="OBJECT"
request_mode="X" request_status="GRANT" request_count="1"
Run Code Online (Sandbox Code Playgroud)在插入的临时表上:
Lock resource_type="OBJECT"
request_mode="X" request_status="GRANT" request_count="1"
Run Code Online (Sandbox Code Playgroud)从 sp_lock(6 和 7 是连接到临时表的数据库,2 是 tempdb):
spid dbid ObjId IndId Type …Run Code Online (Sandbox Code Playgroud) performance sql-server stored-procedures insert sql-server-2012
考虑我有两个表Employee和Department下面给出的字段:
员工:
Fname、Minit、Lname、SsnBdate、地址、性别、薪水、Super_ssn、Dno
部门:
Dname, Dnumber, Mgr_ssn, Mgr_start_date
Italics and code block 表示表的主键。
在上述情况下,Super_Ssn引用SSN员工,而DNO引用该部的Dnumber。为它们创建 sql 非常简单,首先添加列,然后在形成两个表时更改它们。但是,在插入如下所示的数据时:
insert into employee values('James','E','Borg','888665555','1937-11-10','asda','M',55000,NULL,1);
ERROR: insert or update on table "employee" violates foreign key constraint "dno_ref_dnum_dpt"
DETAIL: Key (dno)=(1) is not present in table "department".
Run Code Online (Sandbox Code Playgroud)
和
insert into sp0090.department values ('Headquarter',1,'888665555','1981-06-19');
ERROR: insert or update on table "department" violates foreign key constraint "department_mgr_ssn_fkey"
DETAIL: Key (mgr_ssn)=(888665555) is not …Run Code Online (Sandbox Code Playgroud) 当出现 id 冲突时,我想让 Psycopg2 更新col1、col2和col3。
在我的 Python 代码中,我目前的插入 SQL 为:
insert_sql = '''INSERT INTO {t} (id,col1,col2,col3)
VALUES (%s,%s,NULLIF(%s, 'nan'), NULLIF(%s, 'nan'))
ON CONFLICT (id)
DO NOTHING;'''
Run Code Online (Sandbox Code Playgroud)
基本上我想设置而不是什么都不做:
(col1,col2,col3) = (%s,NULLIF(%s, 'nan'), NULLIF(%s, 'nan'))
忽略插入 ID 并更新 col1、col2 和 col3。问题是%s使用 Psycopg2 在 Python 中传递元组变量:
cur.execute(insert_sql.format(t='my_table'),(int(id),new_col1,new_col2,new_col3))
Run Code Online (Sandbox Code Playgroud)
用于引用%s对应于 col1、col2 和 col3 以更新 ON CONFLICT的语法是什么?
如果我INSERT只在主键尚不存在时才想要一行,INSERT直接执行并在重复的情况下忽略错误是否更有效/更简单,还是应该始终先运行SELECT以检查它是否已经存在?
我只是想知道如果您插入的列数少于表提供的列数,规范是否允许在INSERT语句中排除 column-list 子句。我看到 PostgreSQL 有,而 MySQL 和 SQL Server 没有。
使用 PostgreSQL,(有效)
# CREATE TABLE t (a int, b int);
CREATE TABLE
# INSERT INTO t VALUES (42); -- (b is set to DEFAULT)
INSERT 0 1
Run Code Online (Sandbox Code Playgroud)
使用 SQL Server,我得到
Msg 213 Level 16 State 1 Line 1
Column name or number of supplied values does not match table definition.
Run Code Online (Sandbox Code Playgroud)
使用 MariaDB,我得到
Column count doesn't match value count at row …Run Code Online (Sandbox Code Playgroud) 我想弄清楚是否有一种方法可以使嵌套 CTE 适用于这种特殊情况。
考虑以下基于实际应用程序的(高度人为设计的)场景:有一个员工 ID 的单列表。然后是包含所有详细信息的员工属性表。(单列表背后的主要原因通常是理所当然地需要在知道实际员工的任何详细信息之前批量创建和分配新员工 ID。)
现在到手头的任务,我们要为新员工插入详细信息(即姓名),但首先我们需要检查是否已经存在具有该姓名的员工。如果是,我们将简单地返回 id,如果不是,我们将创建一个新的员工记录,然后插入详细信息,最后返回新创建的 id。
要重新创建此测试场景:
CREATE TABLE public.employee (
id text DEFAULT gen_random_uuid(),
PRIMARY KEY (id)
);
CREATE TABLE public.employee_details (
employee_id text,
name text,
PRIMARY KEY (employee_id),
FOREIGN KEY (employee_id) REFERENCES public.employee(id)
);
Run Code Online (Sandbox Code Playgroud)
我试图敲定的查询如下所示。
with
e as
(select name, employee_id from employee_details where name = 'jack bauer'),
i as (insert into employee_details (name, employee_id)
select 'jack bauer',
(with a as (insert into employee values(default) RETURNING id) select a.id from a)
where not exists …Run Code Online (Sandbox Code Playgroud) 我收到错误 666:
已超出系统为重复组生成的最大唯一值。
我在 Azure SQL 托管实例上遇到了这种情况。
但是,我不应该收到此错误。有问题的索引是bigint identity列上的聚集主键。所以没有重复,也不应该是唯一符。
该表从当前标识为零开始为空。我试图插入 29 亿条记录,让 SQL Server 分配标识密钥。收到错误666后,当前ident为2147483648。
这对我来说没有意义,因为 uniquifier 据说只用于包含重复值的非唯一聚集索引。我的表不符合这些条件。
有没有人有任何想法?
使用INSERT INTO SELECT FROM ORDER BY查询插入记录。除了标识列本身之外,所有列都被指定。我绝对确定标识列的数据类型是BIGINT.
源表是一个没有标识或聚集索引的堆表,所以有bigint问题的列在那里不存在。除了bigint identity添加了列/聚集主键之外,目标表与源表具有重复定义。
我将所有记录从源表插入到目标表,在插入的列列表/选择列表中指定源表中的所有列。该bigint列未在插入中指定,因为它只是目标端的标识列。
我想先用唯一的 id 列(如行号)预先填充我的源堆表,identity_insert在目标表上启用并尝试一次批量插入 100m。那能行吗?
每次此查询失败时,回滚需要 15 个小时。
堆表上有一个按所需插入顺序排列的 NCI,但它不包括所有列,因此会进行书签查找。如果我在加载期间对目标表进行未提交的读取,我可以看到记录,并且标识不断增加。
我看到的最后一个执行计划是表扫描,然后是排序。
我有这个:
CREATE TABLE people
(
id bigserial,
timestamp timestamptz DEFAULT now() NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE "personal information"
(
id bigserial,
"person id" bigint NOT NULL,
timestamp timestamptz DEFAULT now() NOT NULL,
"data's timestamp" timestamptz,
"field" text NOT NULL,
"value" text,
PRIMARY KEY (id),
FOREIGN KEY ("person id") REFERENCES people (id) ON UPDATE CASCADE ON DELETE CASCADE
);
INSERT INTO people RETURNING id; -- Syntax error.
INSERT INTO people; -- Syntax error.
Run Code Online (Sandbox Code Playgroud)
为什么我的插入失败?事实上,“people”表中的所有列都是自动的:该id列是一个 bigserial,并且该列timestamp …
insert ×10
postgresql ×5
sql-server ×3
mysql ×2
upsert ×2
cte ×1
delete ×1
foreign-key ×1
mariadb ×1
oracle-10g ×1
performance ×1
python ×1
sql-standard ×1
syntax ×1
update ×1