我如何知道此补丁是否已应用到我的 SQL Server 服务器?
我知道@@version,但是它显示了应用的最新补丁,那么在此之前的其他补丁呢?
双引号在 SQL Server 中使用,其行为可以通过选项SET QUOTED_IDENTIFIER ON \ OFF来定义
在powershell中也使用双引号。
调用 XML 数据类型方法时,SET QUOTED_IDENTIFIER 必须为 ON。
这是我想要部署到多个服务器的存储过程的部分视图,但是,由于引号标识符或双引号这个字符 - “ - 它在 powershell 中不起作用,在我用来部署的可视化代码中。
DECLARE @WebXConfigurationID INT,
@stored_URL VARCHAR(2000), @cur_URL VARCHAR(2000),
@stored_OpsServiceURL VARCHAR(2000), @cur_OPSServiceURL VARCHAR(2000),
@cur_Properties XML;
PRINT 'WebX Configuration: ' + CAST(@WebXConfigurationID AS VARCHAR(20));
IF (ISNULL(@stored_URL, '') <> ISNULL(@cur_URL, ''))
BEGIN
PRINT ' - Base URL needs updating'
END
ELSE
BEGIN
PRINT ' - Base URL does not need updating'
END;
IF (ISNULL(@stored_OpsServiceURL, '') <> ISNULL(@cur_OPSServiceURL, '') AND @cur_OPSServiceURL IS NOT NULL)
BEGIN
PRINT ' - OPS Service URL needs updating'
SET @cur_Properties.modify('replace value of (/properties[1]//OPSServiceURL[1]/text())[1] with sql:variable("@stored_OpsServiceURL")')
END
ELSE
BEGIN
PRINT ' - OPS Service URL does not need updating'
END;
这是错误信息:
"' in expression or statement.
At C:\sp_PosRestore.ps1:636 char:114
+ ... ServiceURL[1]/text())[1] with sql:variable("@stored_OpsServiceURL")')
+ ~~~~~~~~~~~~~~~~~~~~~
The splatting operator '@' cannot be used to reference variables in an expression. '@stored_OpsServiceURL' can be used only as an argument to a command. To reference variables in an expression use
'$stored_OpsServiceURL'.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : UnexpectedToken
Powershell 代码:
$SQLQuery =
"
DECLARE @WebXConfigurationID INT,
@stored_URL VARCHAR(2000), @cur_URL VARCHAR(2000),
@stored_OpsServiceURL VARCHAR(2000), @cur_OPSServiceURL VARCHAR(2000),
@cur_Properties XML;
PRINT 'WebX Configuration: ' + CAST(@WebXConfigurationID AS VARCHAR(20));
IF (ISNULL(@stored_URL, '') <> ISNULL(@cur_URL, ''))
BEGIN
PRINT ' - Base URL needs updating'
END
ELSE
BEGIN
PRINT ' - Base URL does not need updating'
END;
IF (ISNULL(@stored_OpsServiceURL, '') <> ISNULL(@cur_OPSServiceURL, '') AND @cur_OPSServiceURL IS NOT NULL)
BEGIN
PRINT ' - OPS Service URL needs updating'
SET @cur_Properties.modify('replace value of (/properties[1]//OPSServiceURL[1]/text())[1] with sql:variable("@stored_OpsServiceURL")')
END
ELSE
BEGIN
PRINT ' - OPS Service URL does not need updating'
END;
"
如果您想知道如何临时更改 SQL Server 设置以执行任务并在完成后恢复,有一种方法可以在启用 SQL Server 设置之前保存它们,因此您可以在需要时禁用它们。
以下是代码(部分复制):
IF OBJECT_ID('tempdb.dbo.#Settings') IS NOT NULL
DROP TABLE #Settings;
CREATE TABLE #Settings
(
Setting VARCHAR(100),
Val INT
)
INSERT #Settings (Setting, Val)
SELECT 'show advanced options', cast(value_in_use as int) from sys.configurations where name = 'show advanced options'
UNION
SELECT 'xp_cmdshell', cast(value_in_use as int) from sys.configurations where name = 'xp_cmdshell'
UNION
SELECT 'Ad Hoc Distributed Queries', cast(value_in_use as int) from sys.configurations where name = 'Ad Hoc Distributed Queries'
SELECT * FROM #Settings;
如果您一次运行一个过程,那么效果会很好;但是,它会写入 SQL Server 错误日志,如下所示:
有没有办法避免将设置更改写入错误日志?
正在编写一个删除数据库的脚本。
在某些环境中,我们的数据库会定期从实时状态恢复, 建立复制(合并或事务),运行和测试流程,然后需要删除数据库,因为所有开发都已部署到实时状态,现在开始另一个循环。
作为自动删除数据库的一部分,到目前为止,我给出了以下脚本:
select
DROP_DB_SCRIPT='use master;' + char(13)
+ case when source_database_id is not null -- this is a database snapshot
then ''
else
' alter database ' + name + ' set single_user with rollback immediate ' + -- put db in single user mode
case when (sb.is_published = 1 or sb.is_merge_published = 1)
then 'EXEC sp_removedbreplication ' + '''' + name + '''' -- remove db from the replication
else ''
end +char(13)
end +char(13) +
' drop database ' + quotename(name) +char(13)
,*
from sys.databases sb
where database_id >= 5
and is_distributor= 0
上面的脚本除了生成一个可以用来删除所需数据库或一组数据库的脚本之外不会执行任何其他操作。
它考虑了复制(您需要单独删除复制),并且数据库是否是数据库快照,这是不同的事情。
我没有考虑过以下几点:
在删除 OFFLINE 数据库之前是否应将其设置为 EMERGENCY?
这里的问题是:您是否发现我应该添加但却没有添加任何内容?
我已经处理了两件事:
我还没有处理过:
我最近在网上发现了Alexandr Omelchenko撰写的这篇关于部分备份的精彩文章
-- this is how he would do a backup:
BACKUP DATABASE your_database TO DISK = 'full.bak'
BACKUP DATABASE your_database READ_WRITE_FILEGROUPS TO DISK = 'partial_backup_full.bak'
BACKUP DATABASE your_database READ_WRITE_FILEGROUPS TO DISK = 'partial_backup_diff.bak' WITH DIFFERENTIAL
-- this is how he would do a restore:
RESTORE DATABASE your_database FROM DISK = 'full.bak' WITH NORECOVERY
GO
RESTORE DATABASE your_dataabse FROM DISK = 'partial_backup_full.bak' WITH NORECOVERY
GO
RESTORE DATABASE your_database FROM DISK = 'partial_backup_diff.bak' WITH RECOVERY
GO
碰巧我有几个数据库有 4 个文件组。其中一个文件组加载了保存在该文件组中的一个表中的文档。
我认为单独备份文件组会对我有益。
这样做可能有什么缺点?除了改变restore verifyonly (包括dbaTools ) 的开销以适应此更改并确保使用校验和进行备份之外?
我需要检查的是压缩。另一件事是备份的校验和选项- 正如 Ola 本人在这里和 Paul Randal在这里所建议的那样。
我们绝对需要检查我们的备份是否可靠。
我正在看我的朋友马丁在下面的查询中的一些“工作表”
SELECT st.session_id
,at.*,
case transaction_type
when 1 then 'Read/Write'
when 2 then 'Read-Only'
when 3 then 'System'
when 4 then 'Distributed'
else 'Unknown - ' + convert(varchar(20), transaction_type)
end as tranType,
case transaction_state
when 0 then 'Uninitialized'
when 1 then 'Not Yet Started'
when 2 then 'Active'
when 3 then 'Ended (Read-Only)'
when 4 then 'Committing'
when 5 then 'Prepared'
when 6 then 'Committed'
when 7 then 'Rolling Back'
when 8 then 'Rolled Back'
else 'Unknown - ' + convert(varchar(20), transaction_state)
end as tranState,
case dtc_state
when 0 then NULL
when 1 then 'Active'
when 2 then 'Prepared'
when 3 then 'Committed'
when 4 then 'Aborted'
when 5 then 'Recovered'
else 'Unknown - ' + convert(varchar(20), dtc_state)
end as dtcState
FROM sys.dm_tran_active_transactions at
left JOIN sys.dm_tran_session_transactions st ON st.transaction_id = at.transaction_id
ORDER BY at.transaction_begin_time
引起我注意的一件事是这些交易没有相应的会话?
我怎样才能知道他们来自哪里?
没有与它们关联的会话。
我有一个脚本可以向我展示出版物的复制文章:
declare @publication_name sysname = 'my_pub'
declare @database_name sysname = 'my_db'
use [my_db]
select ServerName = @@servername
,publication_name=p.name
,p.repl_freq
,p.status
,p.sync_method
--,snapshot_job_name=j.name
,p.independent_agent
,p.immediate_sync
,p.allow_anonymous
,p.replicate_ddl
,article_name=OBJECT_SCHEMA_NAME(a.objid) + '.' + OBJECT_NAME(a.objid)
,a.pre_creation_cmd
,pre_creation_cmd_desc = CASE a.pre_creation_cmd
WHEN 0 THEN 'none - Doesn''t use a command.'
WHEN 1 THEN 'drop - Drops the destination table.'
WHEN 2 THEN 'delete - Deletes the destination table.'
WHEN 3 THEN 'truncate - Truncates the destination table.'
ELSE 'Not known - Radhe Radhe'
END
FROM dbo.syspublications P
INNER JOIN dbo.sysarticles A
ON P.pubid = A.pubid
left outer JOIN msdb.dbo.sysjobs j
ON j.job_id = p.snapshot_jobid
where p.name = @publication_name
但是,在我目前正在研究的这个特定出版物中,我也有功能,而这些对象没有显示在上面的查询中?
我知道它们在那里,我怎样才能看到它们?
我得到了这个很棒的查询,它显示了每个现有数据库的最新备份。
SELECT
M.name,
[Recovery Model] =
M.recovery_model_desc,
[State] =
M.state_desc,
[Last Full Backup] =
FORMAT(ISNULL(M.D, '19000101'), 'dd-MM-yyyy hh:mm'),
[Last Differential Backup] =
FORMAT(ISNULL(M.I, '19000101'), 'dd-MM-yyyy hh:mm'),
[Last log Backup] =
FORMAT(ISNULL(M.L, '19000101'), 'dd-MM-yyyy hh:mm')
FROM
(
SELECT
db.name,
db.state_desc,
db.recovery_model_desc,
a.type,
a.backup_finish_date
FROM master.sys.databases AS db
LEFT OUTER JOIN msdb.dbo.backupset AS a
ON a.database_name = db.name
) AS Sourcetable
PIVOT
(
MAX(backup_finish_date)
FOR type IN
(
D,
I,
L
)
) AS M --ostRecentBackup
WHERE name NOT IN
(
N'master',
N'msdb',
N'model',
N'tempdb'
);
我注意到它使用了枢轴 - 如果我还必须添加位置怎么办?那将是多列。
无论是通过使用多列进行旋转,还是逆旋转,我怎样才能将每种备份类型的位置添加到上述查询中?
基本上,最新的完整备份在哪里,最新的差异和最新的日志(如果有)在哪里。
这是我用来查看备份位置的脚本:
SELECT
CONVERT(CHAR(100), SERVERPROPERTY('Servername')) AS Server,
msdb.dbo.backupset.database_name,
msdb.dbo.backupset.TYPE,
msdb.dbo.backupset.backup_start_date,
msdb.dbo.backupset.backup_finish_date,
msdb.dbo.backupset.expiration_date,
msdb.dbo.backupset.backup_size,
msdb.dbo.backupset.backup_size * 1.024 /1024/1024 as [Backup size in MB],
msdb.dbo.backupmediafamily.logical_device_name,
msdb.dbo.backupmediafamily.physical_device_name,
msdb.dbo.backupset.name AS backupset_name,
msdb.dbo.backupset.description
FROM msdb.dbo.backupmediafamily
INNER JOIN msdb.dbo.backupset
ON msdb.dbo.backupmediafamily.media_set_id = msdb.dbo.backupset.media_set_id
--WHERE msdb.dbo.backupset.database_name = 'PivCRM_Prod_Online_ED'
--AND TYPE = 'D' -- L D and I
ORDER BY msdb.dbo.backupset.backup_start_date DESC
问题是:
我该如何将备份的位置(每种类型)添加到第一个查询?
我们最近更改了文件服务器,即存储库(存储备份的地方)服务器。
我注意到硬件特别是 IO 更好,备份需要更短的时间才能完成,这取决于很多因素,但是,恢复仍然需要与以前相同的时间。
这不是一个复杂的问题,我这里只有一个问题:
什么是physical_block_size
?
当您在数据库上运行以下查询时msdb
:
SELECT *
FROM msdb.dbo.backupmediafamily BMF WITH(NOLOCK)
order by 1 desc
这是上述查询的结果,请注意physical_block_size
当我决定使用上面提到的新服务器作为备份目标时,它是如何从 4096 变为 512 的:
使用Ola 的备份策略,有一项工作
数据库备份 - 系统数据库已满,如下图所示。
此项工作计划每周日早上运行一次。
一切都很好,已经运行了一段时间了。
现在我需要将其改为每天运行。
使用 ssms 、编写更改脚本并应用它,效果很好。
然而,因为我需要在几十台服务器上完成这项工作,所以我需要一个脚本来找出时间表,然后修改它并重新应用到工作中
我还没有实现它,但我想知道是否有人已经做到了。
我一直在研究SQL 服务器内部的映射驱动器。
我绘制了类似这样的图:
EXEC XP_CMDSHELL 'net use y: "\\my_server\Initialed Folders\MM" @@__password__@@ /User:mycompany\m_miorelli /persistent:NO'
那已是三个多月前的事了。
现在我已经更改了密码。
然后当我进入同一个服务器时,我们将其称为 my_server,然后运行此
EXEC XP_CMDSHELL 'net use'
我得到这个结果:
你看那里还有 az:驱动器仍然挂在那里,我不知道具体是怎么回事,也许我映射了它......persisted
当我尝试涉及备份所在服务器的任何操作时,我收到此错误消息:
restore filelistonly from disk=N'\\backup_server\ Initialed Folders\MM\backup_of_a_database.bak'
Msg 3201, Level 16, State 2, Line 20
Cannot open backup device '\\backup_server\ Initialed Folders\MM\backup_of_a_database.bak'. Operating system error 1326(The user name or password is incorrect.).
Msg 3013, Level 16, State 1, Line 20
RESTORE FILELIST is terminating abnormally.
我曾尝试这样做:
exec xp_cmdshell 'net use \\ip\xxx pass /user:xxx /persistent:no'
问题):
我怎样才能摆脱该映射驱动器?或者非常具体的目标:我怎样才能摆脱这个错误密码的事情?
其他任何服务器都不会发生这种情况。
按照Craig在评论中的建议,感谢Craig,我删除了映射驱动器
EXEC XP_CMDSHELL 'NET USE Z: /d'
这让我很高兴也很感激,但是,这并没有解决问题。
此触发器在数据库创建时执行操作- 显示了当有人创建新数据库时触发的服务器端触发器的示例。
另一个问题 -创建时触发更改数据库排序规则- 也显示了当有人创建新数据库时触发的服务器端触发器的示例。
这里有一个服务器端触发器的示例,它可以防止用户放弃登录:
USE [master]
GO
--======================================================================
-- example of a server trigger - does not allow a login to be dropped
--======================================================================
create trigger [no_dropped_logins] on all server
for drop_login
as
insert into ##LOGIN_WATCH
select r.*, s.login_name, s.host_name,
EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)') AS 'CmdText'
from sys.dm_exec_requests r
inner join sys.dm_exec_sessions s
on r.session_id = s.session_id
where r.session_id = @@SPID
我的问题是:
如何使用服务器端触发器来防止在 SQL Server 中创建链接服务器?
在尝试防止自动增长发生时,我在这里得到了这个很好的脚本。
然而,如果确实发生了,我需要知道如何找出它。我可以使用Max Vernon 编写的这个非常好的脚本来做到这一点。
print @@servername + ' - ' + SUBSTRING(@@version,1,COALESCE(CHARINDEX('Copyright',@@version,0)-1,108))
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SET NOCOUNT OFF
/*
Description: display growth events for all databases on the instance
by: Max Vernon
date: 2014-10-01
*/
DECLARE @Version NVARCHAR(255);
DECLARE @VersionINT INT;
SET @Version = CONVERT(NVARCHAR(255),SERVERPROPERTY('ProductVersion'));
SET @VersionINT = CONVERT(INT, SUBSTRING(@Version,1 ,CHARINDEX('.',@Version)-1));
DECLARE @cmd NVARCHAR(2000);
SET @cmd = '';
IF @VersionINT >= 9
BEGIN
SET @cmd =
'
DECLARE @trcfilename VARCHAR(1000);
SELECT @trcfilename = path
FROM sys.traces WITH(NOLOCK)
WHERE is_default = 1;
IF COALESCE(@trcfilename,'''') <> ''''
BEGIN
SELECT [Radhe]=
'''''''' + @@SERVERNAME + '''''','''''' +
DB_NAME(mf.database_id) + '''''','''''' +
mf.name + '''''','' +
CONVERT(VARCHAR(255), a.NumberOfGrowths) + '','' +
CONVERT(VARCHAR(255), CAST(a.DurationOfGrowthsInSeconds AS decimal(38, 20)))
FROM
(
SELECT
tt.DatabaseID AS database_id,
tt.FileName AS LogicalFileName,
COUNT(*) AS NumberOfGrowths,
SUM(tt.Duration / (1000 * 1000.0)) AS DurationOfGrowthsInSeconds
FROM sys.fn_trace_gettable(@trcfilename, default) tt
WHERE (EventClass IN (92, 93))
GROUP BY
tt.DatabaseID,
tt.FileName
) a
INNER JOIN sys.master_files mf ON
(mf.database_id = a.database_id) AND
(mf.name = a.LogicalFileName);
END
ELSE
BEGIN
SELECT @@SERVERNAME, ''NO TRACE FILE'';
END
';
EXEC sp_executesql @cmd;
END
ELSE
BEGIN
SELECT [SERVER NAME]=@@SERVERNAME, [Product Version]=SERVERPROPERTY('ProductVersion');
END
缺少的是并且我想补充的是——自动增长是什么时候发生的?
我怎样才能找到它?
当我运行以下脚本时:
-- ——— SCRIPT GRANTS for Object Privileges—————
IF OBJECT_ID('[sys].[sysrowsets]') IS NOT NULL GRANT CONTROL on [sys].[sysrowsets] to [db_myrole_BA]
我收到此错误信息:
Msg 15151, Level 16, State 1, Line 271
Cannot find the object 'sysrowsets', because it does not exist or you do not have permission.
然而:
当我运行这个时:
select radhe=OBJECT_ID('[sys].[sysrowsets]')
我的原始脚本来自这里:
-- SCRIPT GRANTS for Objects Level Privilegs
PRINT '-- ——— SCRIPT GRANTS for Object Privileges—————'
SELECT
[GRANTS for Object Privileges]='IF OBJECT_ID(''['+ sys.schemas.name + '].[' + sys.objects.name + ']''' + ') IS NOT NULL ' + CHAR(13) + SPACE(1) +
state_desc + ' ' + permission_name + ' on ['+ sys.schemas.name + '].[' + sys.objects.name + '] to [' + sys.database_principals.name + ']' COLLATE SQL_Latin1_General_CP1_CI_AS
from sys.database_permissions
join sys.objects on sys.database_permissions.major_id =
sys.objects.object_id
join sys.schemas on sys.objects.schema_id = sys.schemas.schema_id
join sys.database_principals on sys.database_permissions.grantee_principal_id =
sys.database_principals.principal_id
where sys.database_principals.name not in ( 'public', 'guest')
--order by 1, 2, 3, 5
我怎么可能会收到这个错误?
我想保存所有这些权限,以便当我恢复数据库时,我可以重新应用这些权限。
今天我必须检查传输中加密是否在特定服务器(sql服务器)中启动并运行,如果没有,则进行设置。
完成的方式是:
在 SQL Server 配置管理器中,展开 SQL Server 网络配置,右键单击协议,然后选择属性。在标志选项卡上的 ForceEncryption 框中,选择是,然后选择确定以关闭对话框。重新启动 SQL Server 服务。
下面的图片是我重新启动sql server服务之后的。
现在,我是一个喜欢 DBA 天堂的 DBA,喜欢所有自动化和通过脚本完成的事情。
我如何通过脚本完成此操作?部分解决方案也有效。它可以是 powershell、T-SQL 或任何其他脚本语言。
我有一个查询,它显示了服务器中的所有 SQL 服务器实例:
DECLARE @GetInstances TABLE
( Value nvarchar(100),
InstanceNames nvarchar(100),
Data nvarchar(100))
Insert into @GetInstances
EXECUTE xp_regread
@rootkey = 'HKEY_LOCAL_MACHINE',
@key = 'SOFTWARE\Microsoft\Microsoft SQL Server',
@value_name = 'InstalledInstances'
Select [ServerName] = @@servername,InstanceNames from @GetInstances
我还有一个查询,显示特定实例的内存设置和使用情况:
SELECT [instance] = @@servername, p.*
FROM (SELECT name, [value_in_use]
FROM sys.configurations) t
PIVOT (MAX([value_in_use]) FOR name IN ([min server memory (MB)],
[min memory per query (KB)],
[max server memory (MB)],
[optimize for ad hoc workloads])) p
有没有一种方法可以让我同时拥有这两方面的优势 - 通过一个查询获得所有 SQL 服务器实例的所有信息?
我想避免创建链接服务器。
我不介意使用 powershell 或任何其他工具,只要我不需要以管理员身份运行它。
我正在尝试将msdb 作业消息转换为 xml。
我正在使用Ola Hallengren 备份程序。
当我运行以下例程时,它运行惊人并转换所有内容。
现在,如果我将数字 3333 更改为 3702,则会失败。
我无法识别消息中字符 3701 后面的内容,但这阻碍了我将完整消息转换为 xml
如果您使用Ola,您可以在自己的系统上进行测试。如果您知道如何更改我的函数以便我可以成功地将 nvarchar(max) 或varchar(max)转换 为 xml ,请告诉我。
create or alter FUNCTION dbo.fnCleanString (@InputString VARCHAR(MAX))
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE @CleanedString VARCHAR(MAX) = '';
DECLARE @Char VARCHAR(1);
DECLARE @Index INT = 1;
DECLARE @Len INT = 3333-- LEN(@InputString);
WHILE @Index <= @Len
BEGIN
SET @Char = SUBSTRING(@InputString, @Index, 1);
IF (ASCII(@Char) NOT BETWEEN 0 AND 31 OR ASCII(@Char) IN (9, 10, 13))
BEGIN
SET @CleanedString += @Char;
END
SET @Index += 1;
END
RETURN @CleanedString;
END
go
SELECT TOP 50
SysJobs.name,
SysJobs.enabled,
Job.message AS Message_Text,
TRY_CAST(
(SELECT dbo.fnCleanString(Job.message) AS [text()]
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)') AS XML
) AS Message_XML
FROM msdb.dbo.sysjobhistory Job WITH (NOLOCK)
INNER JOIN msdb.dbo.sysjobs SysJobs WITH (NOLOCK)
ON Job.job_id = SysJobs.job_id
WHERE SysJobs.name = 'DatabaseBackup - USER_DATABASES - FULL'
ORDER BY Job.instance_id DESC;