澳门十大赌场最新排名 > 澳门十大赌场 > 开窗函数,Server中DAC连接及别的

原标题:开窗函数,Server中DAC连接及别的

浏览次数:56 时间:2019-07-10

DAC(Dedicated Admin Connection)是SQL Server 2005引入的一个东西,目的是在SQL Server发生严重性能问题的时候仍保留有限的资源保证管理员能够执行一些简单的命令用于问题诊断、释放资源、杀死肇事进程等。微软官方对DAC的说明:使用专用管理员连接.aspx)。对于DAC使用的一般情况,有两个不错的Blog值得推荐:

USE [TestDB]
GO
/****** 对象:  Table [dbo].[Person]    脚本日期: 11/23/2008 13:37:48 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Person](
    [PersonId] [nchar](18) NOT NULL,
    [PersonName] [nchar](20) NOT NULL,
 CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED 
(
    [PersonId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

一个学习性任务:每个人有不同次数的成绩,统计出每个人的最高成绩。

上面的两篇blog涉及到的基本是DAC访问单机单实例的情况。本文试图对DAC访问单机多实例的情况也做个探讨。

默认情况下如果执行一个事务中出现错误,则只回滚错误操作语句(就是说这句不执行了,算不上回滚),错误处之前或之后的正确操作语句还是会被提交。如:

这个问题应该还是相对简单,其实就用聚合函数就好了。

1)单机单SQL Server实例,且SQL Server实例使用默认端口(1433)

Use TestDB

Begin TransAction
    Insert Into Person(PersonId,PersonName)
                Values('1','Name1')
    Insert Into Person(PersonId,PersonName)
                Values('1','Name1')
    Insert Into Person(PersonId,PersonName)
                Values('3','Name3')
Commit TransAction
/*
    Select 一下 有'1','Name1'和'3','Name3',
    说明只有第二句的错误被取消了
*/

select id,name,max(score) from Student group by id,name order by name

--以下的形式都可以访问
sqlcmd -S myServer -U myUser -P myPassword -A
sqlcmd -S ADMIN:myServer -U myUser -P myPassword
sqlcmd -S myServer,1434 -U myUser -P myPassword
sqlcmd -S xxx.xxx.xxx.xxx -U myUser -P myPassword -A
sqlcmd -S xxx.xxx.xxx.xxx,1434 -U myUser -P myPassword

说明:
a) sqlcmd命令行中参数与参数值之间可以有空格也可以没有;如果你的密码中有空格,你可以用双引号把你的密码引起来;
b) sqlcmd命令中的“-S”其实也可以用"/S",其它参数也一样;
c) 1434是SQL Server连接的默认端口号;
d) 在服务器前加"ADMIN:"也是为了指定进行DAC连接;
e) “-A”是在sqlcmd命令行中指定DAC连接的参数;
f) "-A","ADMIN:",",1434"不能在一条命令中出现两个或以上,否则会报错;
g) 不在命令行中加入这3个参数("-A","ADMIN:",",1434")的任何一个,登录也能成功,差别在于你使用的连接是普通连接,不是DAC连接。一般来说,普通连接能用的资源更多,但是当系统性能出现严重问题的时候普通连接可能没法建立,这也是引入DAC的初衷;再就是DAC连接下能看到一些有助于诊断的秘密视图(参见上面推荐的第一个blog)。

全部回滚的方法1:打开 XACT_ABORT

上边这种情况只适用id 和name是一一对应的,否则查询出来的数据是不正确的。

2)单机单SQL Server实例,SQL Server实例使用非默认端口

Use TestDB
SET XACT_ABORT ON -- 打开
Begin TransAction
    Insert Into Person(PersonId,PersonName)
                Values('1','Name1')
    Insert Into Person(PersonId,PersonName)
                Values('1','Name1')
    Insert Into Person(PersonId,PersonName)
                Values('3','Name3')
Commit TransAction
/*
    当 SET XACT_ABORT 为 ON 时,
    如果执行 Transact-SQL 语句产生运行时错误,
    则整个事务将终止并回滚。 
    默认情况下它是OFF状态。
*/

例如 : 1 张三 100

我通过测试得到的结论是:对于单机单SQL Server实例,使用非默认端口时候的DAC访问跟使用默认端口1433时候完全一样。网上的一些论坛说要确保“SQL Server Browser”在运行,似乎不是必要的,至少我测试(用的SQL Server 2008 R2 SP3)过程中“SQL Server Browser”是不是在运行不影响访问。

全部回滚方法2:使用Try...Catch

           2 张三 90

3)单机多SQL Server实例

Use TestDB
Begin Try
    Begin TransAction
        Insert Into Person(PersonId,PersonName)
                    Values('1','Name1')
        Insert Into Person(PersonId,PersonName)
                    Values('1','Name1')
        Insert Into Person(PersonId,PersonName)
                    Values('3','Name3')
    Commit TransAction
End Try
Begin Catch
    Rollback TransAction
End Catch
/*
    使用TryCatch来捕获异常。
    如果 TRY 块内生成的错误导致当前事务的状态失效,
    则将该事务归类为不可提交的事务。
    如果通常在 TRY 块外中止事务的错误在 TRY 内发生时,
    就会导致事务进入不可提交状态。
    不可提交的事务只能执行读操作或 ROLLBACK TRANSACTION。
    该事务不能执行任何可能生成写操作或 COMMIT TRANSACTION 的 Transact-SQL 语句。
    如果事务被分类为不可提交的事务,则 XACT_STATE 函数会返回值 -1。
*/

          查询出来的结果

通过DAC来访问单机多SQL Server实例的情况要复杂一些。上面的几条命令行在这种情况下都会失效。原因在两个:
a) DAC访问是实例级别的,服务端得有办法知道你要访问的是哪个实例;
b) 在单机多实例的情况下监视DAC访问的是随机端口,而不再是默认的1434(当然,具体的端口号在SQL Server启动的时候是确定的,可以在SQL Server启动的Log中找到:打开SSMS--->连接到数据库实例--->Management--->SQL Server Logs--->Current,在里面找到类似”Dedicated admin connection support was established for listening locally on port 50458.“)

--怎么破?
我们在访问数据库引擎的时候,碰到单机多实例的情况有两种办法,一种是在配置S参数的时候加上实例名,一种是加实例端口号。命令行的形式类似下面:
sqlcmd -S myServerInstanceName -U myUser -P myPassword
sqlcmd -S xxx.xxx.xxx.xxxInstanceName -U myUser -P myPassword
sqlcmd -S myServer,6xxx -U myUser -P myPassword
sqlcmd -S xxx.xxx.xxx.xxx,6xxx -U myUser -P myPassword

先从实例名着手:
sqlcmd -S myServerInstanceName -U myUser -P myPassword -A
sqlcmd -S xxx.xxx.xxx.xxxInstanceName -U myUser -P myPassword -A
sqlcmd -S ADMIN:myServerInstanceName -U myUser -P myPassword
sqlcmd -S ADMIN:xxx.xxx.xxx.xxxInstanceName -U myUser -P myPassword

经测试确认,以上4种连接方式都是OK的。注意一点,对于InstanceName的解析是服务器上的“SQL Server Browser”进行的,如果这个服务不在运行,DAC的访问是要失败的。流程是:Browser根据“myServerInstanceName”或者“xxx.xxx.xxx.xxxInstanceName”找到你要访问的实例,然后根据“-A”或者“ADMIN:”找到你要访问的端口。

既然这样可以进行DAC访问,那用类似访问数据库引擎的方式,把上面命令中的“InstanceName”改成",xxxx"格式的端口号是不是也行呢?
sqlcmd -S myServer,xxxx -U myUser -P myPassword -A
sqlcmd -S xxx.xxx.xxx.xxx,xxxx -U myUser -P myPassword -A
sqlcmd -S ADMIN:myServer,xxxx -U myUser -P myPassword
sqlcmd -S ADMIN:xxx.xxx.xxx.xxx,xxxx -U myUser -P myPassword

如果你在几个命令行中配的端口号跟访问数据库引擎时候配置的端口号是一样的话,答案是不行。原因在哪里呢?那个端口是数据库引擎的访问端口,并不是被监听的DAC端口,因为不在一个频道上DAC还不知道你想访问。我的理解,在命令行中指定了端口号的情况下,Browser认为那就是你想访问的端口,结果因为它并不是那个随机的DAC端口而导致了失败。

DAC访问侦听跟数据库引擎一样,从根本上来说也是一个tcp服务(关于这一点你可以查看sys.endpoints来确认)。是服务,我们如果能知道它侦听的端口号就应该能解决问题。但不幸也在这儿,如上面b)所说,在单机多实例的情况下这个被监听的端口是随机的。视图sys.endpoints是能查到当前SQL Server实例上的tcp服务信息的,每个endpoint都有一条记录,比如你就能在这里查到用于镜像的5022,但遗憾的是对于DAC,端口那一列却显示的是0.通过端口访问的这条路我没能走通。

全部回滚方法3:自定义错误变量

          两条信息都会输出。

4)DAC访问与防火墙

Use TestDB
Declare @tranError int -- 定义变量
Set @tranError=0
    Begin TransAction
        Insert Into Person(PersonId,PersonName)
                    Values('1','Name1')
            Set @tranError = @tranError   @@Error
        Insert Into Person(PersonId,PersonName)
                    Values('1','Name1')
            Set @tranError = @tranError   @@Error
        Insert Into Person(PersonId,PersonName)
                    Values('3','Name3')
            Set @tranError = @tranError   @@Error
    If @tranError = 0
        Commit TransAction
    Else
        Rollback TransAction
/*
    自定义一个变量来判断最后是否发生过错误。
*/

避免这种情况,可以使用开窗函数。

本文由澳门十大赌场最新排名发布于澳门十大赌场,转载请注明出处:开窗函数,Server中DAC连接及别的

关键词: bbin宝盈官网

上一篇:没有了

下一篇:没有了