我正在编写一个动态 sql 以在不同的数据库中删除和创建视图。
所以我写道:
set @CreateViewStatement =
'
USE ['+ @DB +'];
CREATE VIEW [dbo].[MyTable]
AS
SELECT ........something
exec (@CreateViewStatement)
Run Code Online (Sandbox Code Playgroud)
它给了我错误:
'CREATE VIEW' 必须是查询批处理中的第一条语句。
如果我删除 USE DATABASE 语句,它可以正常工作,但是不再指定数据库....
我怎么解决这个问题?
我一直在研究 T-SQL 中的代码,以使用 msdb 数据库中的 sp_add_jobschedule proc 向 SQL 代理作业添加新计划。当我添加新计划(通常在特定日期/时间运行一次)并立即查看 sysjobschedules 和 sysschedules 中的值时,我可以看到新计划已添加并与我的 SQL 代理的 job_id 相关联工作。但是,next_run_date 和 next_run_time 的值在其中为 0。当我在 2 或 3 分钟后再次查看它们时,它们仍然显示为 0。但是,当我再过 5 或 10 分钟后再回来时,它现在可以正确显示与下一次计划运行相对应的日期和时间值。
所以我的问题是:
我用来添加新计划的代码示例:
exec msdb.dbo.sp_add_jobschedule @job_id = @jobID
, @name = @JobName
, @enabled = 1
, @freq_type = 1
, @freq_interval = 0
, @freq_subday_type = 0
, @freq_subday_interval = 0
, @freq_relative_interval = 0
, @freq_recurrence_factor = 0
, @active_start_date = …Run Code Online (Sandbox Code Playgroud) 我有一个数据库 Microsoft SQL Server 2008 r2。定义了一个名为 marie 的用户,该用户可以访问主数据库上的表;这很好用。现在,我希望 marie 能够执行此查询:
SELECT resource_type,spid,login_time,status,hostname,program_name,nt_domain,nt_username,loginame
FROM sys.dm_tran_locks dl
JOIN sys.sysprocesses sp on dl.request_session_id = sp.spid
Run Code Online (Sandbox Code Playgroud)
涉及的表是主表;我如何允许玛丽阅读它们?我已经尝试以 dbo 身份执行以下操作:
GRANT ALL on sys.dm_tran_locks TO marie
GRANT ALL on sys.sysprocesses TO marie
Run Code Online (Sandbox Code Playgroud)
尽管如此,当 marie 尝试执行上面的查询时,错误是:
Msg 297, Level 16, State 1, Line 1
The user does not have permission to perform this action.
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
给定一个(简化的)存储过程,例如:
CREATE PROCEDURE WeeklyProc(@endDate DATE)
AS
BEGIN
DECLARE @startDate DATE = DATEADD(DAY, -6, @endDate)
SELECT
-- Stuff
FROM Sale
WHERE SaleDate BETWEEN @startDate AND @endDate
END
Run Code Online (Sandbox Code Playgroud)
如果Sale表很大,SELECT可能需要很长时间才能执行,显然是因为优化器由于局部变量而无法优化。我们测试运行SELECT带有变量的部件,然后硬编码日期,执行时间从约 9 分钟变为约 1 秒。
我们有许多基于“固定”日期范围(周、月、8 周等)进行查询的存储过程,因此输入参数只是 @endDate,@startDate 是在过程中计算的。
问题是,在 WHERE 子句中避免变量以免损害优化器的最佳做法是什么?
我们提出的可能性如下所示。是否有任何这些最佳实践,或者还有其他方法吗?
使用包装程序将变量转换为参数。
参数不会像局部变量那样影响优化器。
CREATE PROCEDURE WeeklyProc(@endDate DATE)
AS
BEGIN
DECLARE @startDate DATE = DATEADD(DAY, -6, @endDate)
EXECUTE DateRangeProc @startDate, @endDate
END
CREATE PROCEDURE DateRangeProc(@startDate DATE, @endDate DATE)
AS
BEGIN
SELECT
-- Stuff
FROM Sale
WHERE SaleDate …Run Code Online (Sandbox Code Playgroud) 我有一个 SQL 查询,我花了两天时间尝试使用试错法和执行计划进行优化,但无济于事。请原谅我这样做,但我会在这里发布整个执行计划。我已经努力使查询和执行计划中的表名和列名通用,既为了简洁又为了保护我公司的 IP。可以使用SQL Sentry Plan Explorer打开执行计划。
我已经完成了大量的 T-SQL,但是使用执行计划来优化我的查询对我来说是一个新领域,我真的试图了解如何去做。所以,如果有人能帮我解决这个问题并解释如何破译这个执行计划以在查询中找到优化它的方法,我将永远感激不尽。我还有更多的查询需要优化——我只需要一个跳板来帮助我完成第一个查询。
这是查询:
DECLARE @Param0 DATETIME = '2013-07-29';
DECLARE @Param1 INT = CONVERT(INT, CONVERT(VARCHAR, @Param0, 112))
DECLARE @Param2 VARCHAR(50) = 'ABC';
DECLARE @Param3 VARCHAR(100) = 'DEF';
DECLARE @Param4 VARCHAR(50) = 'XYZ';
DECLARE @Param5 VARCHAR(100) = NULL;
DECLARE @Param6 VARCHAR(50) = 'Text3';
SET NOCOUNT ON
DECLARE @MyTableVar TABLE
(
B_Var1_PK int,
Job_Var1 varchar(512),
Job_Var2 varchar(50)
)
INSERT INTO @MyTableVar (B_Var1_PK, Job_Var1, Job_Var2)
SELECT B_Var1_PK, Job_Var1, Job_Var2 FROM [fn_GetJobs] (@Param1, @Param2, @Param3, @Param4, …Run Code Online (Sandbox Code Playgroud) sql-server-2008 sql-server optimization t-sql execution-plan
当我查看时sys.sql_logins,我看到一个名为is_policy_checked. 我可以相信我的密码策略已经针对此列值所在的所有登录名进行了检查1吗?
查看Kalen Delaney 撰写的“SQL Server 2008 Internals” 1,第 13 页,它说明了以下内容:
“生成这样一个计划的第一步是规范化每个查询,这可能会将单个查询分解为多个细粒度的查询。查询优化器在规范化一个查询之后对其进行优化,这意味着它确定了一个计划执行该查询。”
另一位 DBA 向我建议,可以通过将WHERE子句谓词移动到FROM子句中来提高某些查询的性能,例如:
SELECT *
FROM dbo.table1 t1
INNER JOIN dbo.table3 t3 ON t1.ID = t3.ID
LEFT OUTER JOIN dbo.table2 t2 ON t1.ID = t2.ID
WHERE t1.CreateDate >= '2015-07-31 00:00:00';
Run Code Online (Sandbox Code Playgroud)
会成为:
SELECT *
FROM dbo.table1 t1
INNER JOIN dbo.table3 t3 ON t1.ID = t3.ID
AND t1.CreateDate >= '2015-07-31 00:00:00'
LEFT OUTER JOIN dbo.table2 t2 ON t1.ID = t2.ID;
Run Code Online (Sandbox Code Playgroud)
显然,第一个示例的含义是查询优化器将执行第JOIN一个, …
这是针对系统操作员(或之前经历过这种经历的人)的一个问题。
我的公司希望在生产中的现有 SQL Server 机器上分配额外的磁盘空间。我们想知道扩展卷(磁盘管理中的“扩展卷...”)是否可以在线完成,或者是否需要关闭 SQL Server 服务。
有什么理由应该停止 SQL Server 服务来执行此操作,还是可以在白天执行此操作?
以防万一系统规格相关。这是一个运行 Windows 2012 R2 和 SQL Server 2008 R2 的真实机器(无虚拟化)。
谢谢!
我正在尝试使用两个原始(即未格式化)分区创建数据库。
Microsoft Docs 声明您可以执行此操作,您只需指定原始分区的驱动器号,如下所示:
CREATE DATABASE DirectDevice
ON (NAME = DirectDevice_system, FILENAME = 'S:')
LOG ON (NAME = DirectDevice_log, FILENAME = 'T:')
Run Code Online (Sandbox Code Playgroud)
但是,SQL Server 2017 返回此错误:
消息 5170,级别 16,状态 4,第 1 行
无法创建文件“S:”,因为它已经存在。更改文件路径或文件名,然后重试该操作。
消息 1802,级别 16,状态 4,第 1 行
创建数据库失败。无法创建列出的某些文件名。检查相关错误。
文档的相关部分指出:
如果文件位于原始分区上,则 os_file_name 必须仅指定现有原始分区的驱动器号。每个原始分区上只能创建一个数据文件。
是的,驱动器 S: 和 T: 都是未格式化的原始分区,它们确实存在于我的系统中:
DISKPART> 详细分区 分区 4 类型:ebd0a0a2-b9e5-4433-87c0-68b6b72699c7 隐藏:否 要求:否 属性:0000000000000000 以字节为单位的偏移量:999934656512 卷 ### Ltr 标签 Fs 类型大小状态信息 ---------- --- ----------- ----- ---------- ------- ---- ----- -------- * 第 6 卷 T RAW …
在谷歌搜索时,我发现了一些相互矛盾的信息。
某些站点指出,当没有为数据留下物理内存时,SQL Server 会将现有数据移动到 TEMPDB(请参阅:SQL Server:揭秘 TempDb 和建议)。
但是其他站点声明,当没有足够的物理内存时,操作系统可以使用 PAGE FILE 并将数据从物理内存移到它(请参阅SQL Server 的页面文件)。
我想知道当 SQL Server 物理内存不足时,它会在哪里写入数据?到 tempdb 还是到 OS Page 文件?或者两者都有?
sql-server ×10
optimization ×2
data-pages ×1
disk-space ×1
dynamic-sql ×1
hardware ×1
logins ×1
memory ×1
password ×1
security ×1
storage ×1
t-sql ×1
tempdb ×1