标签: t-sql

根据另一列值强制一列唯一

我想让一列唯一,但前提是不同的列是特定值。

考虑下表:

CREATE TABLE [SampleTable]
(
     [Id] INTEGER NOT NULL IDENTITY(1,1)
    ,CONSTRAINT [PK_SampleTable]
        PRIMARY KEY ([Id])

    ,[Code]      NVARCHAR(255) NOT NULL
    ,[Deleted]   BIT           NOT NULL DEFAULT 0
    ,[CreatedOn] DATETIME      NOT NULL DEFAULT GETDATE()
);
Run Code Online (Sandbox Code Playgroud)

目的是可以通过将[Deleted]列设置为 1来“删除”项目。

我想要的是将[Code]列强制为唯一,但仅在未删除的行中

在数据库级别强制执行数据正确性通常是我的强烈偏好。但是,我过去经常使用这种模式,但一直不确定是否可以在数据库级别强制实施这种约束。截止日期的压力是什么,我从来没有费心去发现。所以我一直只是在应用程序级别强制执行它们。

如果有办法做到这一点,我真的很想知道它是什么。

需要明确的是,我不能只使用组合唯一约束,因为我需要能够支持以下数据:

    [ID]   [Code]   [Deleted]  [CreatedOn]
=====================================================================
     1     'ABC'    1          Ages ago
     2     'ABC'    1          A while ago
     3     'ABC'    1          Quite recently, actually
     4     'ABC'    0          Just a moment ago!
Run Code Online (Sandbox Code Playgroud)

组合的唯一约束将不起作用,因为就我而言,具有相同代码的三个不同的“已删除”条目是有效的。

我问这个问题是因为最近在集成来自第三方应用程序的数据时,“在应用程序级别强制执行”策略让我感到很恼火。如果数据库直接拒绝错误的集成数据会很好,因为在集成发生之前修复它比在错误发生后清理数据容易得多。

我正在使用 SQL Server 2008 …

sql-server constraint t-sql sql-server-2008-r2

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

在数据库级别设置 ANSI_NULLS 与在表级别设置它

我为我的 sql server 2008 R2 生成了仅模式脚本,这是其中的一部分:-

USE [master]
GO
/****** Object:  Database [****]    Script Date: 03/25/2015 12:17:09 ******/
CREATE DATABASE [****] ON  PRIMARY 
( NAME = N'TMS', FILENAME = N'D:\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\****.mdf' , SIZE = 11264KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
 LOG ON 
( NAME = N'TMS_log', FILENAME = N'L:\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\Data\****.ldf' , SIZE = 4672KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO
ALTER DATABASE [****] SET COMPATIBILITY_LEVEL = 100
GO
IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled')) …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql sql-server-2008-r2 sql-standard

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

有效地重建聚集索引

在测试数据库中,我希望:

  • 删除聚集索引(它们是对我们来说超级无用的行上的主键聚集约束。)
  • 创建新的聚集索引
  • 重新创建主键约束作为非聚集索引
  • 重建所有其他非聚集索引。

我的工作流程也是如此,在删除聚集索引之前添加了禁用所有非聚集索引。

由于删除聚集约束索引需要将表保存为 HEAP,因此此过程在我们的 45m 行表上花费的时间是巨大的。约束的下降一直持续到 1:17:00,似乎只有大约 31m(基于会话的 Spotlight 中的逻辑读取)。

有没有更有效的方法来处理这个工作流程?也许是一种删除约束索引并重建为新聚集索引而不是 HEAP 的方法?

谢谢,韦斯

DDL 语句:

表结构

    CREATE TABLE [dbo].[hist](
    [prrowid] [varchar](36) NOT NULL,
    [part] [varchar](30) NULL,
    [date] [datetime] NULL,
    [per_date] [datetime] NULL,
    [type] [varchar](80) NULL,
    [loc] [varchar](80) NULL,
    [loc_begin] [decimal](28, 10) NULL,
    [begin_qoh] [decimal](28, 10) NULL,
    [qty_req] [decimal](28, 10) NULL,
    [qty_chg] [decimal](28, 10) NULL,
    [qty_short] [decimal](28, 10) NULL,
    [um] [varchar](30) NULL,
    [last_date] [datetime] NULL,
    [nbr] [varchar](30) NULL,
    [so_job] [varchar](80) NULL,
    [ship_type] [varchar](30) NULL,
    [addr] [varchar](80) …
Run Code Online (Sandbox Code Playgroud)

index sql-server clustered-index t-sql sql-server-2014

5
推荐指数
1
解决办法
3809
查看次数

证书、非对称密钥或私钥文件无效或不存在

我正在尝试将数据库从不同的服务器还原到我的本地主机服务器上。那个数据库是加密的(bak 文件),所以我必须解密它,这很好,我有所有的证书文件和密码,但是出于某种原因,我仍然收到以下错误:

The certificate, asymmetric key, or private key file is not valid or does not exist; or you do not have permissions for it.

这是我正在执行的代码:

      CREATE CERTIFICATE [Certificate1] 
FROM FILE = 'C:\Location of the certs'
WITH PRIVATE KEY ( 
    FILE = 'C:\Location of the certs' ,   
    DECRYPTION BY PASSWORD = 'password'
);
Run Code Online (Sandbox Code Playgroud)

附注。我不是备份和恢复方面的专家。

sql-server t-sql restore certificate

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

如何将行转换为 SQL 中的列?

抱歉误导性的问题,但我不知道如何命名我的问题。

我的 db<>fidle 在这里

我有一个定义如下的表:

CREATE TABLE shift (
     worker_name VARCHAR(25), 
     log_time DATETIME, 
     in_out VARCHAR(3)
);
Run Code Online (Sandbox Code Playgroud)

它包含以下数据:

INSERT INTO shift VALUES ('User 1', '2018-05-14 07:24:40.000', 'IN');
INSERT INTO shift VALUES ('User 2', '2018-05-14 11:55:29.000', 'IN');
INSERT INTO shift VALUES ('User 3', '2018-05-14 14:03:26.000', 'IN');
INSERT INTO shift VALUES ('User 1', '2018-05-14 14:05:08.000', 'Out');
INSERT INTO shift VALUES ('User 3', '2018-05-14 20:08:30.000', 'Out');
INSERT INTO shift VALUES ('User 2', '2018-05-14 20:08:36.000', 'Out');
INSERT INTO shift VALUES ('User 4', '2018-05-14 …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql

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

可以通过 DMV 检查 NOEXEC 的状态吗?

在用于部署的大型 DDL 脚本中,将 SET NOEXEC ON 作为错误处理的一部分使用是很常见的,以防止下游代码的执行。如果与 SET NOCOUNT ON 结合使用,则除非进行适当的部署后检查,否则可能会无意中抑制代码执行。我检查了 sys.dm_exec_sessions 并且没有任何 SET 语句的属性。从 DBA 的角度来看,是否有其他方法可以检查当前会话或任何用户会话的任一语句的状态?

这是一个快速示例...

CREATE TABLE dbo.MJZTest
    (Col1 int)
ON [PRIMARY2]
GO
IF @@ERROR<>0
    SET NOEXEC ON

INSERT INTO dbo.MJZTest (Col1)
VALUES (1)
GO
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,如果[PRIMARY2]文件组不存在,阻止了表的创建,@@ERROR检查将调用SET NOEXEC ON阻止后续INSERT语句实际执行的语句。我见过使用 RedGate SQL Compare 等工具生成这种类型的代码。

问题是,如果执行代码的人SET NOEXEC OFF在调试期间忽略运行以重置会话,他们可能会收到一条Command(s) completed successfully.消息,而不管实际结果如何。

sql-server t-sql session

5
推荐指数
1
解决办法
439
查看次数

SQL 挑战 - 传感器阈值异常报告

我添加了一个不使用窗口函数的解决方案和一个基准测试,其中包含一个低于 Martin's Answer 的大数据集

这是GROUP BY 使用不在 SELECT 列表中的列的后续线程- 这什么时候实用、优雅或强大?

在我对这一挑战的解决方案中,我使用了一个查询,该查询按不属于选择列表的表达式进行分组。当逻辑分组元素涉及来自其他行的数据时,这经常与窗口函数一起使用。

也许这是一个矫枉过正的例子,但我认为你可能会发现挑战本身很有趣。我会等待发布我的解决方案,也许你们中的一些人可以提出更好的解决方案。

挑战

我们有一个定期记录读数值的传感器表。无法保证采样时间处于单调间隔。

您需要编写一个查询来报告“异常”,这意味着传感器报告的读数超出阈值的次数,无论是低还是高。传感器报告超过或低于阈值的每个时间段都被视为“例外”。一旦读数恢复正常,异常结束。

示例表和数据

该脚本采用 T-SQL 格式,是我的培训材料的一部分。

这是 SQLFiddle 的链接

------------------------------------------
-- Sensor Thresholds - 1 - Setup Example --
------------------------------------------

CREATE TABLE [Sensors]
(
    [Sensor] NVARCHAR(10) NOT NULL,
    [Lower Threshold] DECIMAL(7,2) NOT NULL,
    [Upper Threshold] DECIMAL(7,2) NOT NULL,
    CONSTRAINT [PK Sensors] 
        PRIMARY KEY CLUSTERED ([Sensor]),
    CONSTRAINT [CK Value Range]
        CHECK ([Upper Threshold] > [Lower Threshold])
);
GO

INSERT INTO [Sensors]
( 
    [Sensor] , …
Run Code Online (Sandbox Code Playgroud)

t-sql window-functions group-by

5
推荐指数
2
解决办法
280
查看次数

优雅地处理 T-SQL 代码中的“类枚举”幻数

我们运行 Dynamics GP,任何处理过 GP 的人都会熟悉它的所有“幻数”列,这些列代表应用程序内的各种枚举值。例如,报告查询可能如下所示:

...
WHERE sod.SOPTYPE = 2
    AND iv.VCTNMTHD = 3
    AND pod.POLNESTA IN (2, 3)
Run Code Online (Sandbox Code Playgroud)

......这与自我记录尽可能远。

起初我有一个聪明的想法,即创建一个名为“Enums”的表,用值填充它,并制作一个标量包装函数,这样你就可以像这样查询:

...
WHERE sod.SOPTYPE = Enum('Sales Doc Type', 'Order')
    AND iv.VCTNMTHD = Enum('Valuation Method', 'Average Perpetual')
    AND pod.POLNESTA IN (Enum('PO Line State', 'Released'), Enum('PO Line State', 'Change Order'))
Run Code Online (Sandbox Code Playgroud)

当然,这很糟糕,因为优化器无法看到潜在的“常量”值,因此做出了一些相当糟糕的选择,因为它必须进行基数猜测。

所以它需要是代码中的实际常量值,但我不确定 SSMS 中是否有任何很好的功能可以使这种事情变得容易。我可以(错误地)以某种方式使用代码片段或模板吗?如果我们可以进行某种查找/插入来使我们的代码看起来像这样,那就太棒了:

...
WHERE sod.SOPTYPE = /*Order*/2
    AND iv.VCTNMTHD = /*Average Perpetual*/3
    AND pod.POLNESTA IN (/*Released*/2, /*Change Order*/3)
Run Code Online (Sandbox Code Playgroud)

我也不反对检查 SSMS 加载项。

sql-server ssms t-sql enum

5
推荐指数
1
解决办法
1233
查看次数

可以定期针对所有视图运行 sp_refreshview 吗?

Microsoft SQL Server 有一个名为sp_refreshview的系统存储过程,它更新传入的视图的元数据。

对我的所有视图定期运行此过程是否有任何不利之处?(例如性能统计受到影响等?)

我可以每晚、每小时、每隔几分钟运行一次吗?

如果这样做没有任何影响,这似乎是确保我的视图元数据在它们引用的基础实体可能发生更改时保持最新的好方法。

sql-server-2008 sql-server stored-procedures metadata t-sql

5
推荐指数
1
解决办法
1316
查看次数

编写一个 T-SQL 存储过程接收 4 个数字并将它们插入到一个表中

我需要编写一个存储过程来接收 4 个数字并将它们插入一个表中。这是我迄今为止开发的:

Declare   
@1  Int = 10,
@2  Int = 20,
@3  Int = 30,
@4  Int = 40


Create table #Temp(Num int)
Declare @I char(1) = 1


 While (@I <= 4)
   Begin

         Insert Into #Temp
         Select @I

     SET @I +=1
   end


Select * from #Temp
Drop table #Temp
Run Code Online (Sandbox Code Playgroud)

我知道我可以直接和静态地将输入插入表中,但我只想知道有没有更好的方法来做到这一点?我想使用一个while语句,但问题是 (I) 变量的数字被插入到表中!!我的意思是输出是 1,2,3,4; 我想要的是 10、20、30、40。

sql-server stored-procedures t-sql

5
推荐指数
3
解决办法
2289
查看次数