因此,我正在从主数据库上的表中的其他服务器导入一些数据
这是通过对目标服务器的查询完成的,但我需要在两台服务器上指定凭据。
因为我必须多次执行此操作,所以我想保存该包,以便以最小的努力就可以更改查询和目标表并再次运行它。
因此,我在源服务器上设置了查询,并在目标服务器上设置了表
我将其设置为将我的包保存到 SQL Server,如下图所示,但是
我可以在哪里看到它?我可以重复使用它吗?
我正在从目标服务器运行它,所以它应该在那里,但是在哪里?
我收到一个查询,要求查找最新的事务日志备份。但由于某种原因,它在此特定服务器中不起作用。
查询如下:
SELECT
@@Servername AS [Server_Name],
B.name AS Database_Name,
ISNULL(STR(ABS(DATEDIFF(day, SYSDATETIME(), MAX(A.backup_finish_date)))), 'NEVER') AS DaysSinceLastBackup,
ISNULL(CONVERT(CHAR(11), MAX(A.backup_finish_date), 113) + ' ' + CONVERT(VARCHAR(8), MAX(A.backup_finish_date), 108), 'NEVER') AS LastBackupDate,
BackupSize_GB = REPLACE(CONVERT(VARCHAR(50), CAST(CAST(COALESCE(MAX(A.compressed_backup_size), MAX(A.backup_size), 0)/1024.0/1024.0/1024.0 AS NUMERIC(18,2)) AS MONEY),1), '.00',''),
BackupSize_MB = REPLACE(CONVERT(VARCHAR(50), CAST(CAST(COALESCE(MAX(A.compressed_backup_size), MAX(A.backup_size), 0)/1024.0/1024.0 AS NUMERIC(18,2)) AS MONEY),1), '.00',''),
[Last Backup Duration (sec)] = DATEDIFF(s, MAX(A.backup_start_date), MAX(A.backup_finish_date)),
[AVG Backup Duration (sec)] = AVG(CAST(DATEDIFF(s, A.backup_start_date, A.backup_finish_date) AS INT)),
[Longest Backup Duration (sec)] = MAX(CAST(DATEDIFF(s, A.backup_start_date, A.backup_finish_date) AS INT)),
[Shortest Backup Duration (sec)] = MIN(CAST(DATEDIFF(s, A.backup_start_date, A.backup_finish_date) AS INT)),
A.type,
media_set_id = MAX(A.media_set_id),
B.create_date,
B.recovery_model_desc,
B.state_desc,
B.is_read_only,
B.database_id,
Backup_Started = MAX(A.backup_start_date),
Backup_Finished = MAX(A.backup_finish_date)
FROM sys.databases B WITH(NOLOCK)
LEFT OUTER JOIN msdb.dbo.backupset A WITH(NOLOCK)
ON A.database_name = B.name
AND A.type = 'L' -- Solo Transaction Log
WHERE 1=1
--B.Name = 'My_database'
GROUP BY
B.Name,
B.database_id,
B.create_date,
B.recovery_model_desc,
B.state_desc,
B.is_read_only,
A.type
有很多种方法可以查看加密过程。
SSMS 中加密过程的示例:
有一个很好的问题:如何查看加密视图或存储过程,您可以看到查看加密过程代码的多种方法,例如使用第三方工具、 专用管理连接、反转RC4 流密码等等,但还有其他很好的答案。
这是使用 DAC 和链接服务器查看加密存储过程代码的另一种引人注目的方式。
那么,我如何在客户的数据库中部署加密的存储过程,以便他们无法解密并查看代码?
过去,他们在自己的存储过程中使用了我们的代码,在许多方面和领域破坏了数据的完整性。我们不希望这种情况再次发生;如果他们需要任何更改或改进,他们可以寻求支持,我们可以安排。
他们托管数据库并拥有完全的访问/控制权,并负责备份、维护等。我无法提供更多细节,也许他们的 DBA 正在阅读这篇文章;)
我在想也许我可以将解密添加或附加到密码中......?
我也会考虑第三方工具。如果您对任何此类工具有积极的体验,请告知,但我更喜欢通过 SQL Server 进行操作。
问题:有没有办法部署无法解密的加密存储过程?
双引号在 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
缺少的是并且我想补充的是——自动增长是什么时候发生的?
我怎样才能找到它?