标签: t-sql

如何限制 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
查看次数

看似相同的 WHERE 子句返回不同的结果

我有一个名为 的表[User]。下面是一个从表中查找一个用户的简单查询:

\n
SELECT  [Username]\n      ,[FirstName]\n      ,[LastName]\n      ,[EmailAddress]\n      ,[IsStaff]\n      ,[ExternalID]\n      ,[LastLogin]\nFROM [dbo].[User]\nWHERE [Username] = 'pskalhaq' -- 1\n--WHERE [Username] = '\xe2\x80\x8fpskalhaq' -- 2\n
Run Code Online (Sandbox Code Playgroud)\n

当我运行此查询时,我得到一条记录,这正是我所期望的。当我注释掉WHERE标记为“1”的子句并取消注释标记为“2”的子句时,我没有得到任何结果。这很奇怪,因为引号之间的值是相同的。

\n

我发现这个问题是因为我编写的一个 Web 应用程序使用实体框架从另一个表获取记录,[Appointment]由于表中没有相关记录而抛出错误[User],即使该[Appointment]表包含不可为空的记录外键连接到[User]表。这似乎是不可能的。我在 SSMS 中运行了等效查询(2892 是给我带来麻烦的约会记录的 ID):

\n
SELECT a.[ID] AS [AppointmentID]\n    ,a.[StudentUsername] -- This is the foreign key in the Appointment table\n    ,u.[Username] -- This is the primary key in the User table\nFROM [dbo].[Appointment] a\nJOIN [dbo].[User] u \nON u.[Username] = a.[StudentUsername]\nWHERE a.[ID] …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql sql-server-2016

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

是否有可靠的方法来检查触发的触发器是否是另一个*特定*触发器的 DML 操作的结果?

当触发器被触发时,是否有任何方法可以从触发器内部判断它是由于另一个特定触发器中发生的 DML 操作而被触发的?

有关调用堆栈的任何信息是否有可能在函数中公开EVENTDATA()?或者其他功能?我宁愿不必分解 XML。

理想情况下,我希望从第二个触发器的范围内获取执行导致第二个触发器触发的 DML 的原始触发器的名称。但我也愿意接受类似的识别来源的方法。

我可以完全控制有问题的两个触发器的代码。

trigger sql-server t-sql standard-edition sql-server-2019

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

如何检查上次执行统计信息的时间?

最近,我们的索引出现了许多问题,我们的 DBA 团队将这些问题归因于最近没有运行的统计数据。这让我想知道 - 我如何检查最近是否通过 SQL Management Studio 更新了统计信息?

如果这个问题没有很好地解释这一点,我深表歉意 - 直到现在我才开始接触统计数据,在此之前,每当我遇到与性能相关的问题时都会查看索引。

编辑

我正在使用以下内容但收到语法错误:

use *databasename*
exec sp_autostats *schema.tablename*
Run Code Online (Sandbox Code Playgroud)

我收到的错误是:

Msg 102, Level 15, State 1, Line 2
Incorrect syntax near '.'.
Run Code Online (Sandbox Code Playgroud)

为什么是这样?

sql-server-2008 sql-server t-sql

11
推荐指数
2
解决办法
4万
查看次数

将日期时间列转换为秒数

在我的 SQL Server 数据库中,我有一datetime列。

创建代表列long值的新列的好方法是什么datetime?在long将表示了若干秒。

我想如果我可以将它转换为longs,那么在一段时间内按查询分组会更容易,因为我可以将长数除以固定数量。

该表是静态的,不会更新或删除数据。

sql-server-2008 sql-server t-sql type-conversion datetime

11
推荐指数
2
解决办法
8万
查看次数

在 100 毫米记录上使用 JOIN 更新,如何做得更好?(在 T-SQL 中)

我需要更新单个表中的 1 亿条记录,实际上,通过用简单的 ID 替换列的 varchar 值来规范化表。(我说的是“替换”,但实际上我是将 ID 写入另一列。)

我想要实现的是规范化数据集。尚未标准化的数据没有索引。我的想法是我不会在原始值上构建索引,而是等待,而是索引将在更新完成后用 tinyint 值替换 varchar 值的外键。

UPDATE A
SET A.AutoClassID = B.AutoClassID
FROM AutoDataImportStaging.dbo.Automobile as A
JOIN AutoData.dbo.AutoClass as B on (A.AutoClassName = B.AutoClassName)
Run Code Online (Sandbox Code Playgroud)

背景

  • 在 Server 2008 R2 上使用 MSSQL 2008 R2
  • 服务器有 8 GB RAM
  • 服务器有一个 RAID10, 7200 RPM SATA(不太好,我知道,在生产中这只会读取数据而不会写入数据;加上最近的 HD 短缺使得这对成本来说是必要的)
  • 服务器具有双四核至强 CPU
  • 机器没有做其他任何事情(目前专用于开发,只有这个过程)
  • 简单日志记录已打开(? - 但它是否仍然记录以便它可以回滚?)
  • 请注意,查询引用了两个不同的数据库,这是值得的
  • 表中记录更新的“宽度”为 455 字节

执行期间的资源

  • 物理内存已满
  • 磁盘 I/O 已满
  • CPU 几乎不做任何事情(阻塞点是 I/O)
  • 运行时间已经 14 小时,而且还在增加!

我怀疑一些事情,比如我需要原始数据的索引,即使我会在规范化更新后删除列 (AutoClassName)。我还想知道我是否应该一次循环一条记录而不是 JOIN,这在我开始时看起来很荒谬,但现在看来会更快。

我应该如何更快地更改剩余标准化更新(类似于此更新)的方法?

sql-server-2008 sql-server t-sql

11
推荐指数
3
解决办法
4040
查看次数

从一个主要作业顺序调用多个 SQL Server 代理作业的好方法?

我有几个应该按顺序运行的 SQL Server 代理作业。为了对应该执行的作业有一个很好的概述,我创建了一个主作业,它通过调用EXEC msdb.dbo.sp_start_job N'TEST1'. 在sp_start_job瞬间完成(作业步骤1),但我想我的主要工作要等到工作TEST1已经调用下一个工作之前完成。

所以我写了这个小脚本,它在作业被调用后立即开始执行(作业步骤 2),并强制主作业等待子作业完成:

WHILE 1 = 1
  BEGIN
    WAITFOR DELAY '00:05:00.000';

    SELECT *
    INTO   #jobs
    FROM   OPENROWSET('SQLNCLI', 'Server=TESTSERVER;Trusted_Connection=yes;',
           'EXEC msdb.dbo.sp_help_job @job_name = N''TEST1'',
           @execution_status = 0, @job_aspect = N''JOB''');

    IF NOT (EXISTS (SELECT top 1 * FROM #jobs))
      BEGIN
        BREAK
      END;

    DROP TABLE #jobs;

  END;
Run Code Online (Sandbox Code Playgroud)

这工作得很好。但我觉得更聪明和/或更安全(WHILE 1 = 1?)的解决方案应该是可能的。

我对以下事情很好奇,希望你能给我一些见解:

  • 这种方法有什么问题?
  • 你能建议一个更好的方法来做到这一点吗?

(我首先在StackOverflow 上发布了这个问题,因为我专注于改进代码。仍然有效。但我的猜测是,这里的人们通常会更聪明地说出为什么我不应该像我那样尝试这样做”我现在就做,或者提供好的替代方案。)

编辑(7 月 25 日)
显然我的脚本没有太多错误,根据指出它问题的答案数量很少:-) 这种脚本的替代方法似乎是使用专为这些设计的工具任务(如 SQL Sentry 事件管理器或...) - …

sql-server t-sql sql-server-2008-r2 sql-server-agent

11
推荐指数
1
解决办法
9766
查看次数

如何通过 SQL Server Management Studio 映射另一台服务器

我正在尝试通过给出命令来映射另一台服务器

EXEC xp_cmdshell 
    'NET USE H:\\568.256.8.358\backup_147 1234abc /USER:cranew /PERSISTENT:yes'
Run Code Online (Sandbox Code Playgroud)

我有一个错误:

找不到网络路径

但我可以手动映射另一台服务器。请帮我解决这个问题。

sql-server-2008 sql-server ssms t-sql

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

某些用户的查询速度很慢

我有几个从 C# .NET web 应用程序调用的查询,它们对我来说总是很快(我是 SQL Server 的本地管理员),但对于一组用户(具有所需权限的域组),查询速度非常慢它在应用程序中超时的点。

什么会导致完全相同的查询对不同的用户以不同的方式运行?

更多信息:

  • 查询是 C# 代码中的内联 SQL,而不是存储过程
  • 该应用程序使用域身份验证,用户和我自己都通过该应用程序运行查询
  • 似乎这个问题是不同的计划,一个被缓存了,所以这就是为什么它对不同的用户是不同的。某些事情正在影响缓存,因为现在通过应用程序查询对我来说很慢,而在 SQL Server Management Studio 中查询速度很快。

performance sql-server-2008 sql-server t-sql

11
推荐指数
2
解决办法
6589
查看次数