我正在修改数据库的结构。表FinancialInstitution的几个列的内容必须转移到表Person 中。金融机构通过外键链接到人。每个金融机构都需要其相应人员的 ID。因此,对于在 Person 中插入的每个新行,必须将该新行的 id (IDENTITY) 复制回 FinancialInstitution 的相应行中。
这样做的明显方法是迭代 T-SQL 代码。但我很想知道是否可以仅使用基于集合的操作来实现。
我想象这样一个请求的内部层次会是这样的:
INSERT INTO Person (Street1, Number1, City1, State1, PostCode1, CountryId1, WorkDirectPhone1, Fax1, Email1)
OUTPUT inserted.Id, FinancialInstitution.Id
SELECT Id, Street, Number, City, [State], PostCode, CountryId, PhoneNumber, Fax, Email
FROM FinancialInstitution;
Run Code Online (Sandbox Code Playgroud)
不幸的是,似乎 OUTPUT 不能以这种方式关联......
鉴于此表:
CREATE TABLE dbo.Target (
TargetId int identity(1, 1) NOT NULL,
Color varchar(20) NOT NULL,
Action varchar(10) NOT NULL, -- of course this should be normalized
Code int NOT NULL,
CONSTRAINT PK_Target PRIMARY KEY CLUSTERED (TargetId)
);
Run Code Online (Sandbox Code Playgroud)
在两个稍微不同的场景中,我想插入行并从标识列返回值。
INSERT dbo.Target (Color, Action, Code)
OUTPUT inserted.TargetId
SELECT t.Color, t.Action, t.Code
FROM
(VALUES
('Blue', 'New', 1234),
('Blue', 'Cancel', 4567),
('Red', 'New', 5678)
) t (Color, Action, Code)
;
Run Code Online (Sandbox Code Playgroud)
CREATE TABLE #Target (
Color varchar(20) NOT NULL,
Action varchar(10) NOT NULL, …
Run Code Online (Sandbox Code Playgroud) 在某些情况下,INSERT INTO <tablename> (WITH TABLOCK)
由于日志记录最少,执行 an会更快。这些情况包括将数据库置于BULK_LOGGED
恢复模型中。
是否有任何其他潜在的性能优势,使用WITH TABLOCK
上INSERT
的空白表时,数据库(tempdb数据库)使用SIMPLE
恢复模式?
我正在使用 SQL Server 2012 标准版。
我的用例是在使用 的存储过程中创建然后立即填充临时表INSERT...SELECT
,其中可能包含多达几百万行。我尽量避免这种tempdb滥用,但有时需要这样做。
我正在尝试构建一个需要 require 的案例TABLOCK
。它似乎不会伤害任何东西,并且可能有好处。我试图弄清楚是否有足够的潜在好处将它添加到我们的代码库中的任何地方,我确信没有其他进程想要写入表。
我通常使用集群 PK 插入新创建的本地临时表,但有时会使用堆。
今天我发现存储我的数据库的硬盘已满。这种情况以前发生过,通常原因很明显。通常有一个错误的查询,这会导致对 tempdb 的大量溢出,它会一直增长到磁盘已满。这次发生的事情不太明显,因为 tempdb 不是驱动器满的原因,而是数据库本身。
事实:
我找到了可能的原因;有一个查询选择了太多的行(错误连接会导致选择 110 亿行,而预计会有几十万行)。这是一个SELECT INTO
查询,这让我怀疑是否可能发生以下情况:
但是,在这种情况下,我不希望 由 创建的表SELECT INTO
仍然存在,它应该被回滚删除。我测试了这个:
BEGIN TRANSACTION
SELECT T.x
INTO TMP.test
FROM (VALUES(1))T(x)
ROLLBACK
SELECT *
FROM TMP.test
Run Code Online (Sandbox Code Playgroud)
这导致:
(1 row affected)
Msg 208, Level 16, State 1, Line 8
Invalid object name 'TMP.test'.
Run Code Online (Sandbox Code Playgroud)
然而目标表确实存在。不过,实际查询并未在显式事务中执行,这能解释目标表的存在吗?
我在这里勾画的假设是否正确?这是可能发生的情况吗?
给定以下堆表,其中包含 400 行,编号从 1 到 400:
DROP TABLE IF EXISTS dbo.N;
GO
SELECT
SV.number
INTO dbo.N
FROM master.dbo.spt_values AS SV
WHERE
SV.[type] = N'P'
AND SV.number BETWEEN 1 AND 400;
Run Code Online (Sandbox Code Playgroud)
以及以下设置:
SET NOCOUNT ON;
SET STATISTICS IO, TIME OFF;
SET STATISTICS XML OFF;
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
Run Code Online (Sandbox Code Playgroud)
以下SELECT
语句在大约6 秒内完成(demo、plan):
DECLARE @n integer = 400;
SELECT
c = COUNT_BIG(*)
FROM dbo.N AS N
CROSS JOIN dbo.N AS N2
CROSS JOIN dbo.N …
Run Code Online (Sandbox Code Playgroud) performance sql-server insert execution-plan query-performance
我正在使用带有 PtokaX API 的 LuaSQL 插入到下表中。
CREATE TABLE `requests` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`ctg` VARCHAR(15) NOT NULL,
`msg` VARCHAR(250) NOT NULL,
`nick` VARCHAR(32) NOT NULL,
`filled` ENUM('Y','N') NOT NULL DEFAULT 'N',
`dated` DATETIME NOT NULL,
`filldate` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `nick_msg` (`nick`, `msg`),
UNIQUE INDEX `ctg_msg` (`ctg`, `msg`)
)
COMMENT='Requests from users in any of the categories.'
COLLATE='utf8_general_ci'
ENGINE=MyISAM;
Run Code Online (Sandbox Code Playgroud)
现在,我的问题是,当用户(由 表示nick
)尝试再次插入相同的请求时,UNIQUE
会检查索引并且脚本返回 false。这会导致我的脚本失败,我必须重新启动脚本。
有什么我可以在
INSERT ... ON DUPLICATE KEY …
我有一个以这种方式创建的表:
--
-- Table: #__content
--
CREATE TABLE "jos_content" (
"id" serial NOT NULL,
"asset_id" bigint DEFAULT 0 NOT NULL,
...
"xreference" varchar(50) DEFAULT '' NOT NULL,
PRIMARY KEY ("id")
);
Run Code Online (Sandbox Code Playgroud)
稍后插入一些行并指定 id:
INSERT INTO "jos_content" VALUES (1,36,'About',...)
稍后,一些记录被插入而没有 id 并且它们因错误而失败:
Error: duplicate key value violates unique constraint
。
显然,id 被定义为一个序列:
每个失败的插入都会增加序列中的指针,直到它增加到一个不再存在的值并且查询成功。
SELECT nextval('jos_content_id_seq'::regclass)
表定义有什么问题?解决这个问题的聪明方法是什么?
我在 MySQL 表中有大约 4000 万行,我想将此表复制到同一数据库中的另一个表。这样做的最有效方法是什么?需要多少时间(大约)?
我们的 ETL 流程有一个长时间运行的 SELECT INTO 语句,它动态地创建一个表,并用数亿条记录填充它。
该声明看起来像 SELECT ... INTO DestTable FROM SrcTable
出于监控目的,我们希望大致了解此语句在执行时的进度(大约行计数、写入的字节数或类似内容)。
我们尝试了以下方法无济于事:
-- Is blocked by the SELECT INTO statement:
select count(*) from DestTable with (nolock)
-- Returns 0, 0:
select rows, rowmodctr
from sysindexes with (nolock)
where id = object_id('DestTable')
-- Returns 0:
select rows
from sys.partitions
where object_id = object_id('DestTable')
Run Code Online (Sandbox Code Playgroud)
此外,我们可以在 中看到事务sys.dm_tran_active_transactions
,但我无法找到一种方法来获取给定的受影响行数transaction_id
(类似于@@ROWCOUNT
也许,但带有transaction_id
as 参数)。
我知道在 SQL Server 上,SELECT INTO 语句是 DDL 和 DML 语句合二为一,因此,隐式表创建将是一个锁定操作。我仍然认为必须有一些聪明的方法来在语句运行时获取某种进度信息。
有一个表“上下文”。有一个自动增量 ID“context_id”。我正在使用序列来检索下一个值。
SELECT nextval('context_context_id_seq')
Run Code Online (Sandbox Code Playgroud)
结果是:1, 2, 3,...20....
但是“上下文”表中有 24780 行
如何获得下一个值 (24781)?
我需要在 INSERT 语句中使用它
insert ×10
sql-server ×6
bulk-insert ×2
mysql ×2
performance ×2
postgresql ×2
duplication ×1
identity ×1
rollback ×1
select ×1
select-into ×1
sequence ×1
update ×1