Archive for 七月, 2013

SQL使用游标对Select结果集循环操作

星期二, 七月 30th, 2013 21 views

首先先简述一下SQL中游标的作用,我们可以将游标理解成一个数组或是一个队列,其保存了Select的结果集的地址队列。
当我们需要对Select的结果集进行循环操作时,可以先定义一个游标,并将结果集指向到这个游标当中,使用游标像指针一样访问这个结果集,如下

①声明游标

1
2
3
DECLARE @id INT --声明一个变量id
DECLARE cur CURSOR read_only FOR --声明一个名为cur的游标
SELECT Userid FROM UserTable WHERE ...... --某Select语句

上述代码意为声明一个游标指向某Select语句的结果集,read_only的意思是这个指针只用于读取,如果更新则需要使用update,这样做的好处是可以明确游标的针对性从而提高执行效率。
DECLARE @id int 意为声明一个变量id,后续会用于从游标指向的结果集中获取数据

创建完游标之后,现在需要打开这个游标并进行操作,语法如下:

②打开游标并读取游标数据

1
2
3
4
5
6
7
8
OPEN cur
Fetch NEXT FROM cur INTO @id --将cur中的下一个数据赋值给变量id

WHILE(@@FETCH_STATUS = 0)
BEGIN
    --要执行的SQL语句
    fetch NEXT FROM cur INTO @id
END

Fetch 的语法如下
Fetch [Next | Prior | First | Last | Absolute n | Relative n ] From 游标名 INTO @变量1,@变量2…

Next:返回结果集中当前行的下一行记录
Prior:返回结果集中当前行的前一行记录,如果第一次读取则没有行返回,并且把游标置于第一行之前。
First:返回结果集中的第一行记录,并且将其作为当前行。
Last:返回结果集中的最后一行,并且将其作为当前行。
Absolute n:当 n > 0 时返回从游标头开始的第n行,并且将其作为当前行;n < 0 时返回从游标末尾开始的第n行,并且将其作为当前行;n = 0 时返回当前行。
Relative n:当 n > 0 时返回从当前行之后的第n行;n < 0 时则返回当前行之前的第n行;n = 0 时返回当前行。

开启游标后,游标指针位于-1行,因此需要使用FETCH NEXT移动到Select的结果集的第一行,
WHILE(@@FETCH_STATUS = 0)循环判断是否有数据,满足条件时将执行Begin和End之间的语句。
每次执行完之后注意使用 Fetch NEXT 移动到下一行。
(更多…)

批处理统计指定服务器端口TCP连接数及拓展工具编写

星期一, 七月 29th, 2013 14 views

最近要对服务器指定端口进行连接数统计,服务器的一些防火墙自带了此功能,但是有时防火墙对流量影响较大,需要关闭防火墙,因此尝试使用批处理创建一个简单查看工具
首先看核心语句

1
2
@echo off
netstat -an | find ":80 " | find "ESTABLISHED" /c

该语句的意思是在netstat -an 的结果中查找满足”:80″的结果 再在其中查找满足 “ESTABLISHED” 的结果 并/c 统计行数
@echo off 的意思是关闭输入命令的回显
接下来我们可以设置其1秒钟执行一次

1
2
3
4
5
6
:loop

//这里加入待循环的语句
timeout /t 1

go loop

此时即基本满足了对指定端口连接数的实时统计。

接下来将进一步利用批处理建立一个迷你的查看工具,首先是定义一下窗口的大小、字体和背景颜色以及标题:

1
mode cols=40 lines=10 & color 2f & title 标题

上述语句意为设置 列数40 行数10 颜色4f(后续有值说明) 以及标题

关于Color的说明如下:

COLOR [attr]

attr 指定控制台输出的颜色属性

颜色属性由两个十六进制数字指定 — 第一个为背景,第二个则为
前景。每个数字可以为以下任何值之一:

0 = 黑色   8 = 灰色
1 = 蓝色   9 = 淡蓝色
2 = 绿色   A = 淡绿色
3 = 浅绿色   B = 淡浅绿色
4 = 红色   C = 淡红色
5 = 紫色   D = 淡紫色
6 = 黄色   E = 淡黄色
7 = 白色   F = 亮白色

结合一下整体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
@echo off
mode con cols=40 lines=10 & color 2f & title BeiTown端口连接数查看器
:loop
    cls
    @echo 当前80端口连接数:
    echo.
    echo.
    netstat -an | find ":80 " | find "ESTABLISHED" /c
    echo.
    echo.
    timeout /t 1
goto loop

将此代码保存为bat格式文件,直接执行即可。
效果如图:

在下一节中我们将简述如何将批处理的回显存入变量中用于进一步编程。

本篇先到此,谢谢关注。

BeiTown
2013.07.29

.NET 验证视图MAC失败 Validation of ViewState MAC Failed 的解决方法

星期日, 七月 28th, 2013 32 views

最近给网站服务器做了集群,即用智能DNS做多台服务器的联合,可以保证在一台网站服务器宕机的情况下,网站不会出现无法访问的情况。但问题随着而来,最近经常有客户反映出现Validation of ViewState MAC Failed 错误。
如图


翻译为:
验证视图MAC失败。如果此应用程序由群集承载,请确保配置指定了相同的 validationKey 和验证算法。不能在群集中使用 AutoGenerate。

在微软官方获得了解决方案。错误原因是集群web服务器应当设置相同的validationKey和decryptionKey。
因为.NET 的很多加密,都是依赖于machineKey中的key,默认情况下.NET 会动态生成这个key,但每台服务器上的动态生成的machinekey值是不一致的,单服务器不会出现问题。
而在集群情况下,machinekey不一致的话,不能共享验证和ViewState,因此对于集群.NET,一定要使用相同的machineKey。
因此需要在web.config中手动添加这个machineKey:

1
2
3
4
5
<system.web>
    <machineKey validationKey="24-64位key(如3FF1E929BC0534950B0920A7B59FA698BD02DFE8)"
   decryptionKey="24-64位key(如280450BB36319B474C996B506A95AEDF9B51211B1D2B7A77)"
   decryption="AES" validation="SHA1"/>
</system.web>

上面的validationKey和decryptionKey都可以自己生成,网上已经很多生成方法,这里直接复制过来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
string validationKey = GetKey(30); //20~64均可
string decryptionKey = GetKey(30); //20~64均可

protected string GetKey(int Keylen)
{
    byte[] bytes = new byte[Keylen];
    new RNGCryptoServiceProvider().GetBytes(bytes);
    StringBuilder Builder = new StringBuilder();
    for (int i = 0; i < bytes.Length; i++)
    {
        Builder.Append(string.Format("{0:X2}", bytes[i]));
    }
    return Builder.ToString();
}

另一种处理方法是直接关闭ViewStateMac功能,在页面头部添加配置信息:enableViewStateMac=”false”
<%@ Page Language="C#" enableViewStateMac="false"%>
但涉及到页面提交,form验证,共享session等功能都需要使用到ViewStateMac,所以此方案无异于自杀,因此也被大多数开发者唾弃。

本文仅供参考,到此搁笔,谢谢关注。

BeiTown
2013.07.28

关于数据库Timeout expired…server is not responding的解决方案

星期三, 七月 3rd, 2013 44 views

当访问一个页面是出现

Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. 

此时表示数据库访问超时,可能此时在执行一个很费时的SQL 操作,而无法在相应时间内给予回复。
关于引起Timeout,比较常见的有可能是因为SqlConnection.ConnectionTimeout引起,或者Connection打开后没有关闭。

在这里还有另一个很有可能,就是你没有设置你的SqlCommand.CommandTimeout。

SqlCommand.CommandTimeout:
获取或设置在终止执行命令的尝试并生成错误之前的等待时间。
等待命令执行的时间(以秒为单位)。默认为 30 秒。

如果设置值 0 ,表示无限制,在CommandTimeout中应避免值 0,否则会无限期地等待执行命令。

另外出现此时错误的原因也有可能是数据库地址错误照成无法连接,此时应当检查数据库连接的配置文件。

同时,对执行SQL语句超时的处理,我们应当尽可能的对数据库的存取过程进行优化,并在读取页面做相应的分页处理等,以避免数据库操作相应时间的超时错误。

关于数据库的优化,之前的博文里已有基本优化方案,更多的方案后续会另外开篇。

本篇到此,谢谢关注。

BeiTown
2013.07.03