标签: t-sql

MERGE 是否使用 tempdb?

考虑以下查询:

MERGE [Parameter] with (rowlock) AS target
    USING (SELECT @AreaId, @ParameterTypeId, @Value)
            AS source (AreaId, ParameterTypeId, Value)
    ON (target.AreaId = source.AreaId AND 
        target.ParameterTypeId = source.ParameterTypeId)
    WHEN MATCHED THEN 
        UPDATE SET target.Value = source.Value, @UpdatedId = target.Id
    WHEN NOT MATCHED THEN
        INSERT ([AreaId], [ParameterTypeId], [Value])
        VALUES (source.AreaId, source.ParameterTypeId, source.Value);
Run Code Online (Sandbox Code Playgroud)

统计 I/O 提供以下输出:

表“参数类型”。扫描计数 0,逻辑读取 2,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
表 'Area'。扫描计数 0,逻辑读取 2,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
表“参数”。扫描计数 1,逻辑读取 4,物理读取 0,预读读取 0,lob 逻辑读取 …

sql-server t-sql

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

Transact-SQL 中的对称差分运算?

我一直都知道UNIONSQL 中的运算符,但直到最近才发现还有其他的集合运算符,INTERSECTEXCEPT. 我一直无法找到执行第四大集合运算符的运算符,即对称差异(例如 . 的相反INTERSECT

看起来我可以通过使用类似的东西来获得所需的输出

SELECT Field FROM A UNION SELECT Field FROM B 
EXCEPT
SELECT Field FROM A INTERSECT SELECT Field FROM B
Run Code Online (Sandbox Code Playgroud)

(假设我得到了正确的优先级),或者通过做一个反完全连接:

SELECT A.Field, B.Field
FROM A
FULL JOIN B ON B.Id = A.Id
WHERE B.Id IS NULL OR A.Id IS NULL
Run Code Online (Sandbox Code Playgroud)

但是这两个看起来都像是相当密集的查询,尤其是与其他三个基本的集合操作相比。SQL中是否存在对称差异操作而我在文档中找不到它?或者是否有一种“规范”的方式在 T-SQL 中实现它?

sql-server t-sql

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

帮助 PIVOT 查询

我有一个具有以下结构的表:

CREATE TABLE [dbo].[AUDIT_SCHEMA_VERSION](
    [SCHEMA_VER_MAJOR] [int] NOT NULL,
    [SCHEMA_VER_MINOR] [int] NOT NULL,
    [SCHEMA_VER_SUB] [int] NOT NULL,
    [SCHEMA_VER_DATE] [datetime] NOT NULL,
    [SCHEMA_VER_REMARK] [varchar](250) NULL
);
Run Code Online (Sandbox Code Playgroud)

一些示例数据(似乎 sqlfiddle 有问题.. 所以放一些示例数据):

INSERT INTO [AUDIT_SCHEMA_VERSION]([SCHEMA_VER_MAJOR],[SCHEMA_VER_MINOR],[SCHEMA_VER_SUB],[SCHEMA_VER_DATE],[SCHEMA_VER_REMARK])
VALUES(1,6,13,CAST('20130405 04:41:25.000' as DATETIME),'Stored procedure build')
INSERT INTO [AUDIT_SCHEMA_VERSION]([SCHEMA_VER_MAJOR],[SCHEMA_VER_MINOR],[SCHEMA_VER_SUB],[SCHEMA_VER_DATE],[SCHEMA_VER_REMARK])
VALUES(1,6,13,CAST('20130405 04:41:25.000' as DATETIME),'Stored procedure build')
INSERT INTO [AUDIT_SCHEMA_VERSION]([SCHEMA_VER_MAJOR],[SCHEMA_VER_MINOR],[SCHEMA_VER_SUB],[SCHEMA_VER_DATE],[SCHEMA_VER_REMARK])
VALUES(1,7,13,CAST('20130405 04:41:25.000' as DATETIME),'Stored procedure build')
INSERT INTO [AUDIT_SCHEMA_VERSION]([SCHEMA_VER_MAJOR],[SCHEMA_VER_MINOR],[SCHEMA_VER_SUB],[SCHEMA_VER_DATE],[SCHEMA_VER_REMARK])
VALUES(1,10,13,CAST('20130405 04:41:25.000' as DATETIME),'Stored procedure build')
INSERT INTO [AUDIT_SCHEMA_VERSION]([SCHEMA_VER_MAJOR],[SCHEMA_VER_MINOR],[SCHEMA_VER_SUB],[SCHEMA_VER_DATE],[SCHEMA_VER_REMARK])
VALUES(1,12,13,CAST('20130405 04:41:25.000' as DATETIME),'Stored procedure build')
INSERT INTO [AUDIT_SCHEMA_VERSION]([SCHEMA_VER_MAJOR],[SCHEMA_VER_MINOR],[SCHEMA_VER_SUB],[SCHEMA_VER_DATE],[SCHEMA_VER_REMARK])
VALUES(1,12,13,CAST('20130405 04:41:25.000' as DATETIME),'Stored …
Run Code Online (Sandbox Code Playgroud)

sql-server pivot t-sql sql-server-2008-r2

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

使用“WITH NOCHECK”创建外键时会丢失什么?

我知道,如果我EXISTS()调用 FK 查找值,那么,如果该 FK 约束是可信的,那么结果是立竿见影的。

如果它不受信任(比如我使用 来创建 FK 时WITH NOCHECK),那么 SQL Server 必须去检查表以查看该值是否确实存在。

使用我还有什么损失NOCHECK吗?

foreign-key sql-server t-sql

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

这个while循环是否需要显式事务?

SQL Server 2014:

我们有一个非常大(1 亿行)的表,我们需要更新其中的几个字段。

对于日志运输等,我们显然也希望将其保持为一口大小的交易。

如果我们让下面运行一会儿,然后取消/终止查询,那么到目前为止所做的工作会全部提交,还是需要添加明确的 BEGIN TRANSACTION / END TRANSACTION 语句以便我们可以随时取消?

DECLARE @CHUNK_SIZE int
SET @CHUNK_SIZE = 10000

UPDATE TOP(@CHUNK_SIZE) [huge-table] set deleted = 0, deletedDate = '2000-01-01'
where deleted is null or deletedDate is null

WHILE @@ROWCOUNT > 0
BEGIN
    UPDATE TOP(@CHUNK_SIZE) [huge-table] set deleted = 0, deletedDate = '2000-01-01'
    where deleted is null or deletedDate is null
END
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql transaction sql-server-2014

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

如何隐藏/禁用表而不删除它们以检查冗余?

我必须维护和扩展一个旧的遗留系统,其中包含不再使用的 web 服务方法和数据库表。由于我不完全确定这些表是否真的是多余的,因此我害怕删除它们。

有没有其他方法可以在不删除它们的情况下实现相同的效果(不能再使用表格)?我的想法是将它们Deleted从当前默认的dbo.

IF NOT EXISTS (SELECT * FROM sys.schemas WHERE name = 'Deleted')
BEGIN
   EXEC('CREATE SCHEMA Deleted')
END

ALTER SCHEMA Deleted TRANSFER dbo.TableName;
Run Code Online (Sandbox Code Playgroud)

有没有其他选择或者模式方法有什么缺点?

database-design sql-server t-sql sql-server-2012

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

带有输出的 MERGE 是否比条件插入和选择更好的做法?

我们经常会遇到“如果不存在,则插入”的情况。Dan Guzman 的博客对如何使此进程线程安全进行了出色的调查。

我有一个基本表,它只是将字符串从SEQUENCE. 在存储过程中,我需要获取该值的整数键(如果它存在),或者INSERT它然后获取结果值。该dbo.NameLookup.ItemName列有一个唯一性约束,因此数据完整性没有风险,但我不想遇到异常。

这不是一个IDENTITY所以我无法获得,SCOPE_IDENTITY并且NULL在某些情况下价值可能是。

在我的情况下,我只需要处理INSERT桌面上的安全问题,所以我试图决定是否使用MERGE这样的方法更好:

SET NOCOUNT, XACT_ABORT ON;

DECLARE @vValueId INT 
DECLARE @inserted AS TABLE (Id INT NOT NULL)

MERGE 
    dbo.NameLookup WITH (HOLDLOCK) AS f 
USING 
    (SELECT @vName AS val WHERE @vName IS NOT NULL AND LEN(@vName) > 0) AS new_item
        ON f.ItemName= new_item.val
WHEN MATCHED THEN
    UPDATE SET @vValueId = f.Id
WHEN NOT MATCHED BY TARGET THEN
    INSERT …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql merge sql-server-2014

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

MS-SQL 上是否有任何(隐藏的)内置函数来取消引用对象名称?

有时我将对象名称(标识符)存储在我们的一些数据库中,例如在一些参数表中。因为我使用 '=' 或 'LIKE' 比较运算符从这些表中选择记录,所以我必须注意存储这些名称时总是带括号或不带括号

IF EXISTS (SELECT 1 FROM MYTABLE WHERE OBJ_NAME = '[TABLE_NAME]';
Run Code Online (Sandbox Code Playgroud)

或者

IF EXISTS (SELECT 1 FROM MYTABLE WHERE OBJ_NAME = 'TABLE_NAME';
Run Code Online (Sandbox Code Playgroud)

但是,MS-SQL 有一些函数,您可以在其中使用带或不带括号的对象名称,例如 OBJECT_ID() 函数。我在dbfiddle.uk上设置了一个最小的例子。

CREATE TABLE TEST
(
    ID     INT IDENTITY(1,1) PRIMARY KEY,
    OBJECT sysname NOT NULL
);
GO

INSERT INTO TEST VALUES ('[obj1]'),('obj2'),('obj3'),('[obj4]');
GO
Run Code Online (Sandbox Code Playgroud)

现在我可以使用 OBJECT_ID() 以这种方式检查表 TEST 是否存在:

IF OBJECT_ID('TEST') IS NOT NULL
BEGIN
    SELECT 'TEST EXISTS.' OBJECT_ID;
END
GO

| OBJECT_ID    |
| :----------- | …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql

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

如何限制 SQL 存储过程一次只能由一个人运行?

我有一个存储过程,它基本上从一个表中选择值并将它们插入到另一个表中,这是一种归档。我想避免多人同时这样做。

当这个程序正在运行时,我不希望其他人能够启动它,但是我不希望序列化,另一个人在我完成后运行该程序。

我想要的是其他人在我运行该程序时尝试启动它以获取错误。

我尝试过使用 sp_getapplock,但是我无法完全阻止该人运行该程序。

我还尝试使用 sys.dm_exec_requests 查找过程并阻止该过程,虽然这确实有效,但我认为这不是最佳选择,因为在某些服务器上我没有运行 sys.dm_exec_sql_text(sql_handle) 的权限。

我这样做的最佳方法是什么?

sql-server stored-procedures t-sql sql-server-2012

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

为什么要使用master来创建数据库?

我有一个简短的问题,为什么要使用use master;创建数据库?这是Microsoft 文档中的示例

USE master ;
GO
CREATE DATABASE Sales
ON
( NAME = Sales_dat,
    FILENAME = 'C:\Program Files\...\saledat.mdf',
    SIZE = 10,
    MAXSIZE = 50,
    FILEGROWTH = 5 )
LOG ON
( NAME = Sales_log,  
    FILENAME = 'C:\Program Files\...\salelog.ldf',
    SIZE = 5MB,
    MAXSIZE = 25MB,
    FILEGROWTH = 5MB ) ;
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql ddl master-system-database

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