多种方式的md5加密

一、oracle实现md5加密:

CREATE OR REPLACE function fn_md5(input_string VARCHAR2) return varchar2
IS
raw_input RAW(128) := UTL_RAW.CAST_TO_RAW(input_string);
decrypted_raw RAW(2048);
error_in_input_buffer_length EXCEPTION;
BEGIN
sys.dbms_obfuscation_toolkit.MD5(input => raw_input,checksum => decrypted_raw);
return rawtohex(decrypted_raw);
END;


二、mysql实现md5加密:

select upper(md5('abc')) from cdb_settings limit 1;


注意问题:在mysql中不知道为什么使用了upper不能转化为大写,尝试了几个编码的mysql库都不行,也许是我mysql版本的问题,先记录下mysql版本

三、Sql Server 实现md5加密

select hashbytes('MD5', 'abc');


四、C#实现md5加密:

string abc=System.Web.Security.FormsAuthentication.
HashPasswordForStoringInConfigFile("abc", "MD5") ;
 Response.Write(abc);


五、Javascript实现md5加密:

var hexcase = 0; function hex_md5(a)
{ return rstr2hex(rstr_md5(str2rstr_utf8(a))) }
function hex_hmac_md5(a, b)
{ return rstr2hex(rstr_hmac_md5(str2rstr_utf8(a), str2rstr_utf8(b))) }
 function md5_vm_test()
{ return hex_md5("abc").toLowerCase() == "900150983cd24fb0d6963f7d28e17f72" }
 function rstr_md5(a)
{ return binl2rstr(binl_md5(rstr2binl(a), a.length * 8)) }
 function rstr_hmac_md5(c, f)
{ var e = rstr2binl(c); if (e.length > 16)
{ e = binl_md5(e, c.length*8) }
 var a = Array(16), d = Array(16);
 for (var b = 0; b < 16; b++)
{ a[b] = e[b] ^ 909522486; d[b] = e[b] ^ 1549556828 }
var g = binl_md5(a.concat(rstr2binl(f)), 512 + f.length * 8);
return binl2rstr(binl_md5(d.concat(g), 512 + 128)) }
function rstr2hex(c) { try { hexcase } catch (g) { hexcase = 0 }
 var f = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
 var b = ""; var a; for (var d = 0; d < c.length; d++) { a = c.charCodeAt(d);
 b += f.charAt((a >>> 4) & 15) + f.charAt(a & 15) } return b } function str2rstr_utf8(c)
 { var b = ""; var d = -1; var a, e; while (++d < c.length)
{ a = c.charCodeAt(d); e = d + 1 < c.length ? c.charCodeAt(d + 1) : 0;
 if (55296 <= a && a <= 56319 && 56320 <= e && e <= 57343)
{ a = 65536 + ((a & 1023) << 10) + (e & 1023); d++ }
if (a <= 127) { b += String.fromCharCode(a) }
else { if (a <= 2047) { b += String.fromCharCode(192 | ((a >>> 6) & 31),
 128 | (a & 63)) } else { if (a <= 65535) { b += String.fromCharCode(224
| ((a >>> 12) & 15), 128 | ((a >>> 6) & 63), 128 | (a & 63)) }
else { if (a <= 2097151) { b += String.fromCharCode(240 |
((a >>> 18) & 7), 128 | ((a >>> 12) & 63), 128 | ((a >>> 6) & 63),
 128 | (a & 63)) } } } } } return b } function rstr2binl(b)
{ var a = Array(b.length >> 2); for (var c = 0; c<a.length; c++)
 { a = 0 } for (var c = 0; c <b.length*8;c =c+8 )
{ a |= (b.charCodeAt(c / 8 ) & 255) << (c % 32) } return a }
function binl2rstr(b) { var a = ""; for (var c = 0; c<b.length * 32; c=c+8)
 { a += String.fromCharCode((b >>> (c % 32)) & 255) }
 return a } function binl_md5(p, k) { p[k >> 5] |= 128 << ((k) % 32);
p[(((k + 64) >>> 9) << 4) + 14] = k; var o = 1732584193;
var n = -271733879; var m = -1732584194; var l = 271733878;
 for (var g = 0; g < p.length; g += 16) { var j = o; var h = n;
var f = m; var e = l; o = md5_ff(o, n, m, l, p[g + 0], 7, -680876936);
 l = md5_ff(l, o, n, m, p[g + 1], 12, -389564586); m = md5_ff(m, l, o, n, p[g + 2], 17, 606105819);
n = md5_ff(n, m, l, o, p[g + 3], 22, -1044525330); o = md5_ff(o, n, m, l, p[g + 4], 7, -176418897);
l = md5_ff(l, o, n, m, p[g + 5], 12, 1200080426); m = md5_ff(m, l, o, n, p[g + 6], 17, -1473231341);
 n = md5_ff(n, m, l, o, p[g + 7], 22, -45705983); o = md5_ff(o, n, m, l, p[g + 8], 7, 1770035416);
l = md5_ff(l, o, n, m, p[g + 9], 12, -1958414417); m = md5_ff(m, l, o, n, p[g + 10], 17, -42063);
 n = md5_ff(n, m, l, o, p[g + 11], 22, -1990404162); o = md5_ff(o, n, m, l, p[g + 12], 7, 1804603682);
 l = md5_ff(l, o, n, m, p[g + 13], 12, -40341101); m = md5_ff(m, l, o, n, p[g + 14], 17, -1502002290);
n = md5_ff(n, m, l, o, p[g + 15], 22, 1236535329); o = md5_gg(o, n, m, l, p[g + 1], 5, -165796510);
 l = md5_gg(l, o, n, m, p[g + 6], 9, -1069501632); m = md5_gg(m, l, o, n, p[g + 11], 14, 643717713);
n = md5_gg(n, m, l, o, p[g + 0], 20, -373897302); o = md5_gg(o, n, m, l, p[g + 5], 5, -701558691);
 l = md5_gg(l, o, n, m, p[g + 10], 9, 38016083); m = md5_gg(m, l, o, n, p[g + 15], 14, -660478335);
n = md5_gg(n, m, l, o, p[g + 4], 20, -405537848); o = md5_gg(o, n, m, l, p[g + 9], 5, 568446438);
l = md5_gg(l, o, n, m, p[g + 14], 9, -1019803690); m = md5_gg(m, l, o, n, p[g + 3], 14, -187363961);
 n = md5_gg(n, m, l, o, p[g + 8], 20, 1163531501); o = md5_gg(o, n, m, l, p[g + 13], 5, -1444681467);
 l = md5_gg(l, o, n, m, p[g + 2], 9, -51403784); m = md5_gg(m, l, o, n, p[g + 7], 14, 1735328473);
n = md5_gg(n, m, l, o, p[g + 12], 20, -1926607734); o = md5_hh(o, n, m, l, p[g + 5], 4, -378558);
l = md5_hh(l, o, n, m, p[g + 8], 11, -2022574463); m = md5_hh(m, l, o, n, p[g + 11], 16, 1839030562);
 n = md5_hh(n, m, l, o, p[g + 14], 23, -35309556); o = md5_hh(o, n, m, l, p[g + 1], 4, -1530992060);
 l = md5_hh(l, o, n, m, p[g + 4], 11, 1272893353); m = md5_hh(m, l, o, n, p[g + 7], 16, -155497632);
n = md5_hh(n, m, l, o, p[g + 10], 23, -1094730640); o = md5_hh(o, n, m, l, p[g + 13], 4, 681279174);
l = md5_hh(l, o, n, m, p[g + 0], 11, -358537222); m = md5_hh(m, l, o, n, p[g + 3], 16, -722521979);
n = md5_hh(n, m, l, o, p[g + 6], 23, 76029189); o = md5_hh(o, n, m, l, p[g + 9], 4, -640364487);
l = md5_hh(l, o, n, m, p[g + 12], 11, -421815835); m = md5_hh(m, l, o, n, p[g + 15], 16, 530742520);
n = md5_hh(n, m, l, o, p[g + 2], 23, -995338651); o = md5_ii(o, n, m, l, p[g + 0], 6, -198630844);
l = md5_ii(l, o, n, m, p[g + 7], 10, 1126891415); m = md5_ii(m, l, o, n, p[g + 14], 15, -1416354905);
n = md5_ii(n, m, l, o, p[g + 5], 21, -57434055); o = md5_ii(o, n, m, l, p[g + 12], 6, 1700485571);
l = md5_ii(l, o, n, m, p[g + 3], 10, -1894986606); m = md5_ii(m, l, o, n, p[g + 10], 15, -1051523);
n = md5_ii(n, m, l, o, p[g + 1], 21, -2054922799); o = md5_ii(o, n, m, l, p[g + 8], 6, 1873313359);
 l = md5_ii(l, o, n, m, p[g + 15], 10, -30611744); m = md5_ii(m, l, o, n, p[g + 6], 15, -1560198380);
n = md5_ii(n, m, l, o, p[g + 13], 21, 1309151649); o = md5_ii(o, n, m, l, p[g + 4], 6, -145523070);
l = md5_ii(l, o, n, m, p[g + 11], 10, -1120210379); m = md5_ii(m, l, o, n, p[g + 2], 15, 718787259);
n = md5_ii(n, m, l, o, p[g + 9], 21, -343485551); o = safe_add(o, j); n = safe_add(n, h);
m = safe_add(m, f); l = safe_add(l, e) } return Array(o, n, m, l) }
function md5_cmn(h, e, d, c, g, f) { return safe_add(bit_rol(safe_add(safe_add(e, h),
safe_add(c, f)), g), d) } function md5_ff(g, f, k, j, e, i, h)
{ return md5_cmn((f & k) | ((~f) & j), g, f, e, i, h) } function md5_gg(g, f, k, j, e, i, h)
{ return md5_cmn((f & j) | (k & (~j)), g, f, e, i, h) } function md5_hh(g, f, k, j, e, i, h)
{ return md5_cmn(f ^ k ^ j, g, f, e, i, h) } function md5_ii(g, f, k, j, e, i, h)
{ return md5_cmn(k ^ (f | (~j)), g, f, e, i, h) } function safe_add(a, d)
{ var c = (a & 65535) + (d & 65535); var b = (a >> 16) + (d >> 16) + (c >> 16);
return (b << 16) | (c & 65535) } function bit_rol(a, b) { return (a << b) | (a >>> (32 - b)) }

实现:

<script src="md5-min.js" type="text/javascript"></script>
 <script type="text/javascript">
 alert('abc经过md5加密后结果为:\n'+hex_md5('abc'));
 </script>


六、php实现md5加密:

echo strtoupper(md5('abc')) ;

oracle之修改跟踪文件

该文件目的:是跟踪自上一个增量备份以来哪些块已经修改。
启用:alter database enable block change tracking using file ‘path+filename’
关闭:alter database disable block change tracking;
注意:1)关闭之后,原来的跟踪文件也被删除(本人在windows上测试没有被删除)
2)开启跟踪会消耗系统不小的资源,要慎重

oracle之password file

1、作用:
允许远程SYSDBA 或管理员访问数据库,如果没有这个文件验证,即使是sysdba权限的用户,也不能在数据库文件没有加载之前登录数据库,让其加载数据库。
2、创建命令:
直接dos或者linux命令行下:orapwd file= password= entries= force=
file——密码文件名(必要)。
password——SYS 的密码(必要)。
entries——DBA 和操作员的最大数目(可选)。
force——是否重写现有的文件(可选)。
等号(=)两边没有空格。
注:win下放置在%ORACLE_HOME%\database目录下,文件名为PW%ORACLE_SID%.ora;
linux下放置在$ORACLE_HOME/dbs目录下,文件名为orapw$ORACLE_SID

oracle之存储体系

(1) 数据库由一个或多个表空间组成
(2) 表空间由一个或多个数据文件组成。这些文件可以是文件系统中的cooked 文件、原始分区、ASM管理的数据库文件,或集群文件系统上的文件。表空间包含段。
(3) 段(TABLE、INDEX 等)由一个或多个区段组成。段在表空间中,但是可以包含这个表空间中多个数据文件中的数据。
(4) 区段是磁盘上一组逻辑连续的块。区段只在一个表空间中,而且总是在该表空间内的一个文件中。
(5) 块是数据库中最小的分配单位,也是数据库使用的最小I/O 单位。
(6)oracle中的块是操作系统物理块的整数倍

oracle之trace file

1、设置SQL_TRACE=TRUE,服务器就会生成一个包含性能相关信息的跟踪文件。
2、跟踪文件位置:
如果使用专用服务器连接,会在USER_DUMP_DEST 参数指定的目录中生成跟踪文件;
如果使用共享服务器连接,则在BACKGROUND_DUMP_DEST 参数指定的目录中生成跟踪文件。
可以通过SHOW PARAMETER DUMP_DEST或者select name, value from v$parameter where name like ‘%dump_dest%’来查询
3、获得跟踪文件名(标准格式:_ora_.trc):

select d.value||'/'||lower(rtrim(i.instance,chr(0)))||'_ora_'||p.spid||'.trc' trace_file_name
from (select p.spid
from v$mystat m, v$session s,v$process p
where m.statistic# = 1 and
s.sid = m.sid and
p.addr = s.paddr ) p,
( select t.instance
from v$thread t,v$parameter v
where v.name = 'thread' and
(v.value = 0 or t.thread# = to_number(v.value))) i,
( select value from v$parameter where name = 'user_dump_dest') d;

oracle之spfile

1、在修改spfile命令如:
Alter system set parameter=value <comment=’text’> <deferred>
<scope=memory|spfile|both> <sid=’sid|*’>
说明:comment表示说明,deferred表示重启后生效
2、查询哪些参数在修改时,必须使用deferred参数
select name from v$parameter where issys_modifiable=’DEFERRED’;
在10g中的结果是:
backup_tape_io_slaves
audit_file_dest
object_cache_optimal_size
object_cache_max_size_percent
sort_area_size
sort_area_retained_size
olap_page_pool_size
3、取消spfile中值的设置
Alter system reset parameter sid=’sid|*’
说明:这里的sid不能省略
4、查看oracle使用spfile还是pfile
Select isspecified,count(*) from v$spparameter group by isspecified;
如果isspecified里有true,表明用spfile进行了指定配置
如果全为false,则表明用pfile启动

mysql数据管理

本人的兴趣一直都是oracle数据库的管理,最近公司上电子商务系统,现在还处于测试状态,不出意外应该没有大问题,因为程序是 php+mysql的,这就涉及到程序的维护、数据库的维护和管理。虽然mysql数据库在一般情况下,直接复制数据库下的data文件夹下面的数据库名 的文件夹可以备份
如 上图,这里我选中的每一文件夹其实是mysql数据库的一个数据库,只要直接复制就可以备份相应的数据库了,但是考虑到系统实时性可能比较高,如果这样备 份,肯定会导致数据的丢失,还有就是因为系统里面的数据库有60多张表,一张表又有三个文件,如果数据量大的时候,备份起来时间比较长
所有决定写一个脚本使用命令mysqldump+windows系统的任务自动定时执行备份,并实现为了方便转移,打包压缩功能

@echo off
echo 批发网中文版和英文版数据库备份
echo.
echo 程序启动时间:%date% %time%
echo.
set "Name=%date:~,4%%date:~5,2%%date:~8,2%_%random%"
set "Path=e:\MySql_BackUp\%Name%"
md %Path%
echo 保存备份数据库文件路径为:%Path%
echo ***********************************************************
echo.
echo %time%:开始备份db_glasses_en数据库……
echo.
e:\AppServ\MySQL\bin\mysqldump --opt -u root --password=4020894 -F -B --default-character-set=utf8 db_glasses_en_bak > %Path%\db_glasses_en_bak.sql
echo 文件:%Path%\db_glasses_en_bak.sql
echo %time%:db_glasses_en数据库备份完成
echo.
echo ***********************************************************
echo.
echo %time%:开始备份db_glasses_cn数据库……
echo.
e:\AppServ\MySQL\bin\mysqldump --opt -u root --password=4020894 -F -B --default-character-set=utf8 db_glasses_cn > %Path%\db_glasses_cn_bak.sql
echo 文件:%Path%\db_glasses_cn_bak.sql
echo %time%:db_glasses_cn数据库备份完成
echo.
echo ***********************************************************
echo.
echo 批发网中英文数据库备份完成……
echo.
echo ***********************************************************
echo.
echo %time%:备份数据库进行压缩……
cd C:\Program Files\WinRAR
WinRAR.exe a -m5 e:\MySql_BackUp\%Name%.rar %Path%
echo.
echo %time%:e:\MySql_BackUp\%Name%.rar压缩完成
echo 请检查文件并做好数据转移……
echo.
echo 程序结束时间:%date% %time%
echo.
echo ***********************************************************
pause

通过上面的脚本实现数据库的备份,结果如下图:

上图即为执行备份后的结果,至于mysql的备份命令mysqldump的相关参数请见mysql的相关文档。
补充说明:
在 mssql里面日志是自动启动的;在oracle归档日志默认情况下是关闭的,可以在mount模式下,使用alter database archivelog开启重做日志归档模式;在mysql中,日志默认情况下也是关闭的,但是它是通过修改my.ini配置文件实现修改的,具体参数如 下:
log-bin=F:\AppServ\MySQL\log\log_bin.log
log=F:\AppServ\MySQL\log\log.log
log-update= F:\AppServ\MySQL\log\update.log
log-slow-queries=F:\AppServ\MySQL\log\mysql-slow.log
log-error=F:\AppServ\MySQL\log\error.log
各日志参数说明:
错误日志:   -log-err
查询日志:   -log
慢查询日志:     -log-slow-queries
更新日志:     -log-update
二进制日志:   -log-bin
注:如果日志参数后面直接跟文件名,那日志文件会放置在mysql/data文件夹下

服务器遭攻击,oracle分析日志

今天公司服务器出现问题,经过启动日志功能,分析日志,大概确定是dos攻击
部分日志如下:

2010-07-02 10:55:22 W3SVC689347672 192.168.10.222 GET /index.shtml -  80 - 121.204.33.120  Mozilla/4.0(compatible;+MSIE+7.0;+Windows+NT+5.1;+SV1) 200 0 64
2010-07-02  10:55:22 W3SVC689347672 192.168.10.222 GET /index.shtml - 80 -  114.41.216.107 Mozilla/4.0(compatible;+MSIE+7.0;+Windows+NT+5.1;+SV1)  200 0 64
2010-07-02 10:55:22 W3SVC689347672 192.168.10.222 GET  /index.shtml - 80 - 221.15.37.5  Mozilla/4.0(compatible;+MSIE+7.0;+Windows+NT+5.1;+SV1) 200 0 64
2010-07-02  10:55:22 W3SVC689347672 192.168.10.222 GET /index.shtml - 80 -  114.41.216.107 Mozilla/4.0(compatible;+MSIE+7.0;+Windows+NT+5.1;+SV1)  200 0 64
2010-07-02 10:55:22 W3SVC689347672 192.168.10.222 GET  /index.shtml - 80 - 114.41.216.107  Mozilla/4.0(compatible;+MSIE+7.0;+Windows+NT+5.1;+SV1) 200 0 64
2010-07-02  10:55:22 W3SVC689347672 192.168.10.222 GET /index.shtml - 80 -  114.41.216.107 Mozilla/4.0(compatible;+MSIE+7.0;+Windows+NT+5.1;+SV1)  200 0 64
2010-07-02 10:55:22 W3SVC689347672 192.168.10.222 GET  /index.shtml - 80 - 114.41.216.107  Mozilla/4.0(compatible;+MSIE+7.0;+Windows+NT+5.1;+SV1) 200 0 64
2010-07-02  10:55:22 W3SVC689347672 192.168.10.222 GET /index.shtml - 80 -  222.81.14.4 Mozilla/4.0(compatible;+MSIE+7.0;+Windows+NT+5.1;+SV1) 200 0  64
2010-07-02 10:55:22 W3SVC689347672 192.168.10.222 GET  /index.shtml - 80 - 180.126.191.98  Mozilla/4.0(compatible;+MSIE+7.0;+Windows+NT+5.1;+SV1) 200 0 64
2010-07-02  10:55:22 W3SVC689347672 192.168.10.222 GET /index.shtml - 80 -  117.15.210.226 Mozilla/4.0(compatible;+MSIE+7.0;+Windows+NT+5.1;+SV1)  200 0 64
2010-07-02 10:55:22 W3SVC689347672 192.168.10.222 GET  /index.shtml - 80 - 121.204.33.120  Mozilla/4.0(compatible;+MSIE+7.0;+Windows+NT+5.1;+SV1) 200 0 64
2010-07-02  10:55:22 W3SVC689347672 192.168.10.222 GET /index.shtml - 80 -  112.122.131.60 Mozilla/4.0(compatible;+MSIE+7.0;+Windows+NT+5.1;+SV1)  200 0 64
2010-07-02 10:55:22 W3SVC689347672 192.168.10.222 GET  /index.shtml - 80 - 118.77.181.47  Mozilla/4.0(compatible;+MSIE+7.0;+Windows+NT+5.1;+SV1) 200 0 64

日志文件实在太多了,最后几分钟都就有20m左右,我们肉眼看上去,没有什么规律可寻的,我决定采用oracle数据帮我们分析
建表如下:
get   varchar2(3000)–保存日志中的一条记录
ip varchar2(15)–保存日志中请求服务器的ip地址(分析的重点)
gettime varchar2(20)  –保存时间(本来有date类型的,不知道为什么,和后面的proc中的程序有的冲突,我也不想改存储过程了,就先改了这个,有时间再想想程序)
第一步:通过net把.log 的日志文件中的数据导入到db的dos_gj中的get列中,程序如下:

string txt = Show_page("log.log");
string[] aba = txt.Replace("\r\n", "@").Split('@');
for (int i = 0; i < aba.Length; i++)
{
OracleHelper.ExecuteNonQuery(OracleHelper.
ConnectionStringLocalTransaction,
System.Data.CommandType.Text,
"insert into dos_gj(get) values (:abc)", new OracleParameter("abc", aba[i]));
}

//读取文件的 Show_page()函数就不放出来了

大概半个多小时,20m文件的数据,全部分条导入到数据中,统计,一共近20w条
第二步:使用proc对这些数据进行分析:
proc如下 :

create or replace
procedure dos_fx
is
cursor c1 is
select get from dos_gj;
begin
for c2 in c1 loop
update dos_gj set
ip=REGEXP_SUBSTR( get, '(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])(\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])){3} '),
gettime=REGEXP_SUBSTR( get, '\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}') where get=c2.get;
end loop;
commit;
end;
exec  dos_fx;

不知道什么原因,执行了快两个小时了,现在还是在执行中,我现在怀疑在oracle中cursor +正则表达式+update,执行效率正的很低啊,才20w条数据,执行了2个小时,还没有结果,郁闷,在等待中……
这些对oracle有点无语了,害的我现在还不能睡觉,等在电脑面前,早知道就用ms sql了,听说 2005也支持正则功能了。继续等待(2010年7月3日2:04:58),这个效率,这个速度有点无语哦,听说oracle速度很快,我还得好好学习 哦。等了两个多小时就是学艺不精的后果。
最后想想这个update table的思路不行,新建了一张,使用了新的存储过程(insert)

create or replace procedure dos_fx
is
cursor c1 is
select get from dos_gj;
begin
for c2 in c1 loop
insert into dos_gj_1(ip,gettime,get)values(REGEXP_SUBSTR( c2.get,  '(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])(\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])){3}  '),
REGEXP_SUBSTR( c2.get, '^(\d{4})-(\d{2})-(\d{2}) (\d{2}:\d{2}:\d{2})'),c2.get);
end loop;
commit;
end;

同上表,然后执行insert操作,考虑到sql dev占用内存太大,这次使用了pl/sql dev操作,结果使用了1分钟37秒就完成了近20w的数据的操作,这才是oracle的本色啊,O(∩_∩)O哈哈~。
现在想想,应该是刚刚前面的update那种操作导致了数据库死锁导致无限的等待。

好了,数据从log文件,到数据库里面,已经数据提取成功,剩下的就是相关统计的oracle了
统计ip攻击情况

不到一个小时的攻击的结果大概如上图,任务大概完成,先睡觉去,明天继续分析

通过sql server 数据库中的sql语句实现项目需求

最近都关注oracle,今天没有办法,因为项目使用的是sql server数据库,许多东西都忘记的差不多了。需要实现一个功能,本来可以使用程序去实现,但是我不爽,一定想通过数据库本身来解决这个问题。问题大概是:
项目中是要实现在别人寻找到宝贝后,要回答一个问题,这个问题暂时定为有四个选项,其中一个正确的,在数据库中使用两张表来实现,一张是记录问题的题目和答案(表一),另一张表专门用来记录每个题目中的选项(表二),表的sql脚本如下:
表一:

USE [xb_new]
GO
/****** 对象:  Table [dbo].[Question]    脚本日期: 06/13/2010 21:17:05 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Question](
[id] [int] IDENTITY(1,1) NOT NULL,
[iss_id] [int] NULL,
[answer] [nvarchar](50) NULL,
[question] [nvarchar](150) NULL,
CONSTRAINT [PK_Question_] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH  (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF,  ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

表中数据如下:

表二:

USE [xb_new]
GO
/****** 对象:  Table [dbo].[Qusetion_Answer]    脚本日期: 06/13/2010 21:18:12 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Qusetion_Answer](
[id] [int] IDENTITY(1,1) NOT NULL,
[qid] [int] NOT NULL,
[qtext] [nvarchar](50) NOT NULL,
[qvalue] [nvarchar](2) NULL
) ON [PRIMARY]

表中数据如下

现在需求是:把一个题目的四个选项合并到一起,并为了在网页上换行,显示题目,显示答案。
其中难道是行列转换,以前在orcal中都是使用decode来实现的,现在郁闷的sql server中竟然不支持这个函数,只能我在oracle中比较讨厌的case(主要要多写很多when、then、end我不喜欢,而且还容易忘记格 式)来实现。实现sql脚本如下:

SELECT a,q,aa+'<br>'+bb+'<br>'+cc+'<br>'+dd result FROM
(SELECT DISTINCT answer a,Question.Question q,
aa=MAX(CASE qvalue WHEN 'A' THEN '(A)'+qtext END),
bb=max(CASE qvalue WHEN 'B' THEN '(B)'+qtext END),
cc=max(CASE qvalue WHEN 'C' THEN '(C)'+qtext END),
dd=max(CASE qvalue WHEN 'D' THEN '(D)'+qtext END)
FROM dbo.Question,dbo.Qusetion_Answer
WHERE qid=dbo.Question.id GROUP BY dbo.Question.answer,Question.Question) temp;

结果如下:

存储过程实现:更新、插入、删除、再插入

已经在空间上放了好几篇存储过程的东西了,本来这个不想再放上去了,但是想想,为了这个思路的完整性,还是把这个存储过程也给放上来
这次实现的是从回收站还原的功能,整体思路是,先更新所需的档案件号,然后复制到对应的部门表中,然后删除回收站表的数据,再把刚刚到部门表中的数据插入到总表中,使得部门的表和总表数据一致

ALTER PROC [dbo].[add_data_yes]
@tablename varchar(30),
@id INT,
@jh INT
AS
declare @sql nvarchar(4000)
SET @sql=N'update S_del set jh='+CAST(@jh AS VARCHAR(10))+N' where id='+CAST(@id AS VARCHAR(10))+N';INSERT INTO <a href="mailto:%27+@tablename+N%27" target="_blank">'+@tablename+N'</a>
( tm ,
jh ,
ajh ,
gjz ,
sjms ,
fsdd ,
fsrq ,
zyrw ,
psz ,
psrq ,
tgz ,
zrz ,
sc ,
ly ,
cjh ,
srz ,
flh ,
dph ,
bz ,
xpdx ,
xpgs ,
xpxs ,
scrid ,
scr ,
scsj ,
scbm ,
shr ,
shsj ,
ecbz ,
gdr ,
gdsj ,
xgsj ,
flag ,
ysurl ,
ysfile ,
xgurl ,
xgfile ,
xwurl ,
xwnr ,
textall
)
SELECT
tm ,
jh ,
ajh ,
gjz ,
sjms ,
fsdd ,
fsrq ,
zyrw ,
psz ,
psrq ,
tgz ,
zrz ,
sc ,
ly ,
cjh ,
srz ,
flh ,
dph ,
bz ,
xpdx ,
xpgs ,
xpxs ,
scrid ,
scr ,
scsj ,
scbm ,
shr ,
shsj ,
ecbz ,
gdr ,
gdsj ,
xgsj ,
flag ,
ysurl ,
ysfile ,
xgurl ,
xgfile ,
xwurl ,
xwnr ,
textall
FROM S_del WHERE id='+CAST(@id AS varchar(10))+N';delete from S_del  where id='+CAST(@id AS varchar(10))+N';insert into S_bm_all select *  from <a href="mailto:%27+@tablename+N%27" target="_blank">'+@tablename+N'</a> where id=(select max(id) from <a href="mailto:%27+@tablename+N%27%29%27" target="_blank">'+@tablename+N')'</a>
EXEC(@sql)

好了,以前是因为自己对存储过程没有入门,写了几个放在上面了,现在感觉对存储过程有了一点状态,不再放存储过程山来了(我感觉特别有意义的除外)