Archive for 四月, 2010

– Triggers 2 – Creating Audit Trails Author Nigel Rivett

星期四, 四月 29th, 2010

Sql Server. Triggers 2 – Creating Audit Trails – Author Nigel Rivett

– Triggers 2 – Creating Audit Trails
Author Nigel Rivett

Creating Audit Trails
Author: Nigel Rivett

Objective
The objective of an audit trail is to log changes to data in tables.

This article deals with two ways of creating an audit trail:

1. Audit trail table for each table to be audit trailed

Create a copy of the table and write copies of the rows to it.
For this method it is usual to write the old data only as the new data is in the main table and to write an entry whether or not anything is actaully changed.
This can be implemented in triggers or in the stored procedures that update the data.
This method also does not require a primary key as it is just saving the before versions of rows updated.

2. Single audit trail table

Create a table to log the table name, field name abd old and new versions of the data.
For this method it is usual to log both old and new versions of the data and only those fields that have changed.
To implement this in triggeres it is a requirement that either there is a primary key on the table or only single rows are updated.

Note that text and image columns are not available in the insertd/deleted tables to after triggers so these cannot be saved by this method.

Test table to be audit trailed.
if exists (select * from sysobjects where id = object_id(N’[dbo].[trigtest]‘) and OBJECTPROPERTY(id, N’IsUserTable’) = 1)
drop table [dbo].[trigtest]
go
create table trigtest (i_int_key int not null, j_int_key int not null, s_varchar varchar(10), t_char varchar(10), d_date datetime)
go
alter table trigtest add constraint pk primary key (i_int_key, j_int_key)
go

Test updates
insert trigtest (i_int_key, j_int_key, s_varchar, t_char, d_date)
select 1, 1, ‘hello’, ‘goodbye’, ‘20000101′
insert trigtest (i_int_key, j_int_key, s_varchar, t_char, d_date)
select 2, 1, ‘hello’, ‘goodbye’, ‘20000101′
update trigtest set s_varchar = ‘helloupd’ where i_int_key = 1
update trigtest set t_char = ‘goodbyeupd’, d_date = ‘20000102′ where i_int_key = 1
update trigtest set t_char = null, d_date = null where i_int_key = 1
update trigtest set t_char = ‘good’, d_date = ‘20000103′ where i_int_key = 1
delete trigtest where i_int_key = 1

1. Audit trail table for each table to be audited

Audit trail table

if exists (select * from sysobjects where id = object_id(N’[dbo].[trigtest_au]‘) and OBJECTPROPERTY(id, N’IsUserTable’) = 1)
drop table [dbo].[trigtest_au]
go
create table trigtest_au (i_int_key int not null, j_int_key int not null, s_varchar varchar(10), t_char varchar(10), d_date datetime, UpdateDate datetime, UserName varchar(128), type varchar(10))
go

Trigger to create the audit trail for the table

To only save only the old copy of the data

if exists (select * from dbo.sysobjects where id = object_id(N’[dbo].[tr_au_trigtest]‘) and OBJECTPROPERTY(id, N’IsTrigger’) = 1)
drop trigger [dbo].[tr_au_trigtest]
go
create trigger tr_au_trigtest on trigtest for update, delete
as
declare @type varchar(1) ,
@UpdateDate datetime ,
@UserName varchar(128)
if exists (select * from inserted)
select @type = ‘U’
else
select @type = ‘D’

select @UpdateDate = getdate() ,
@UserName = system_user

insert trigtest_au (i_int_key, j_int_key, s_varchar, t_char, d_date, UpdateDate, UserName, type)
select i_int_key, j_int_key, s_varchar, t_char, d_date, @UpdateDate, @UserName, @type + ‘_old’
from deleted
go

To save the old and new copy of the data

if exists (select * from dbo.sysobjects where id = object_id(N’[dbo].[tr_au_trigtest]‘) and OBJECTPROPERTY(id, N’IsTrigger’) = 1)
drop trigger [dbo].[tr_au_trigtest]
go
create trigger tr_au_trigtest on trigtest for insert, update, delete
as
declare @type varchar(1) ,
@UpdateDate datetime ,
@UserName varchar(128)
if exists (select * from inserted) and exists (select * from deleted)
select @type = ‘U’
else if exists (select * from inserted)
select @type = ‘I’
else
select @type = ‘D’

select @UpdateDate = getdate() ,
@UserName = system_user

insert trigtest_au (i_int_key, j_int_key, s_varchar, t_char, d_date, UpdateDate, UserName, type)
select i_int_key, j_int_key, s_varchar, t_char, d_date, @UpdateDate, @UserName, @type + ‘_old’
from deleted
insert trigtest_au (i_int_key, j_int_key, s_varchar, t_char, d_date, UpdateDate, UserName, type)
select i_int_key, j_int_key, s_varchar, t_char, d_date, @UpdateDate, @UserName, @type + ‘_new’
from inserted
go

2. Single Audit Trail table.

Audit trail table
if exists (select * from sysobjects where id = object_id(N’[dbo].[trigtest_au]‘) and OBJECTPROPERTY(id, N’IsUserTable’) = 1)
drop table [dbo].[trigtest_au]
go
create table trigtest_au (TableName varchar(128), FieldName varchar(128), OldValue varchar(1000), NewValue varchar(1000), UpdateDate datetime, UserName varchar(128), type varchar(1))
go

Trigger to save old and new values of fields that have changed

if exists (select * from dbo.sysobjects where id = object_id(N’[dbo].[tr_au_trigtest]‘) and OBJECTPROPERTY(id, N’IsTrigger’) = 1)
drop trigger [dbo].[tr_au_trigtest]
go
create trigger tr_au_trigtest on trigtest for insert, update, delete
as
declare @type varchar(1) ,
@UpdateDate datetime ,
@UserName varchar(128)
if exists (select * from inserted) and exists (select * from deleted)
select @type = ‘U’
else if exists (select * from inserted)
select @type = ‘I’
else
select @type = ‘D’

select @UpdateDate = getdate() ,
@UserName = system_user

if update (i_int_key) or @type = ‘D’
insert trigtest_au (TableName, PK, FieldName, OldValue, NewValue, UpdateDate, UserName, type)
select ‘trigtest’, convert(varchar(20),coalesce(d.i_int_key,i.i_int_key)) + ‘|’ + convert(varchar(20),coalesce(d.j_int_key,i.j_int_key)), ‘i_int_key’, convert(varchar(1000),d.i_int_key), convert(varchar(1000),i.i_int_key), @UpdateDate, @UserName, @type
from inserted i
full outer join deleted d
on i.i_int_key = d.i_int_key
and i.j_int_key = d.j_int_key
where (i.i_int_key <> d.i_int_key or (i.i_int_key is null and d.i_int_key is not null) or (i.i_int_key is not null and d.i_int_key is null))
if update (j_int_key) or @type = ‘D’
insert trigtest_au (TableName, PK, FieldName, OldValue, NewValue, UpdateDate, UserName, type)
select ‘trigtest’, convert(varchar(20),coalesce(d.i_int_key,i.i_int_key)) + ‘|’ + convert(varchar(20),coalesce(d.j_int_key,i.j_int_key)), ‘j_int_key’, convert(varchar(1000),d.j_int_key), convert(varchar(1000),i.j_int_key), @UpdateDate, @UserName, @type
from inserted i
full outer join deleted d
on i.i_int_key = d.i_int_key
and i.j_int_key = d.j_int_key
where (i.j_int_key <> d.j_int_key or (i.j_int_key is null and d.j_int_key is not null) or (i.j_int_key is not null and d.j_int_key is null))
if update (s_varchar) or @type = ‘D’
insert trigtest_au (TableName, PK, FieldName, OldValue, NewValue, UpdateDate, UserName, type)
select ‘trigtest’, convert(varchar(20),coalesce(d.i_int_key,i.i_int_key)) + ‘|’ + convert(varchar(20),coalesce(d.j_int_key,i.j_int_key)), ’s_varchar’, convert(varchar(1000),d.s_varchar), convert(varchar(1000),i.s_varchar), @UpdateDate, @UserName, @type
from inserted i
full outer join deleted d
on i.i_int_key = d.i_int_key
and i.j_int_key = d.j_int_key
where (i.s_varchar <> d.s_varchar or (i.s_varchar is null and d.s_varchar is not null) or (i.s_varchar is not null and d.s_varchar is null))
if update (t_char) or @type = ‘D’
insert trigtest_au (TableName, PK, FieldName, OldValue, NewValue, UpdateDate, UserName, type)
select ‘trigtest’, convert(varchar(20),coalesce(d.i_int_key,i.i_int_key)) + ‘|’ + convert(varchar(20),coalesce(d.j_int_key,i.j_int_key)), ‘t_char’, convert(varchar(1000),d.t_char), convert(varchar(1000),i.t_char), @UpdateDate, @UserName, @type
from inserted i
full outer join deleted d
on i.i_int_key = d.i_int_key
and i.j_int_key = d.j_int_key
where (i.t_char <> d.t_char or (i.t_char is null and d.t_char is not null) or (i.t_char is not null and d.t_char is null))
if update (d_date) or @type = ‘D’
insert trigtest_au (TableName, PK, FieldName, OldValue, NewValue, UpdateDate, UserName, type)
select ‘trigtest’, convert(varchar(20),coalesce(d.i_int_key,i.i_int_key)) + ‘|’ + convert(varchar(20),coalesce(d.j_int_key,i.j_int_key)), ‘d_date’, convert(char(9),d.d_date,112) + convert(char(8),d.d_date,8), convert(char(9),i.d_date,112) + convert(char(8),i.d_date,8), @UpdateDate, @UserName, @type
from inserted i
full outer join deleted d
on i.i_int_key = d.i_int_key
and i.j_int_key = d.j_int_key
where (i.d_date <> d.d_date or (i.d_date is null and d.d_date is not null) or (i.d_date is not null and d.d_date is null))
go

This gives the following result

select TableName = convert(char(12),TableName), PK = convert(char(6),PK), FieldName = convert(char(16),FieldName),
OldValue = convert(char(20),OldValue), NewValue = convert(char(20), NewValue),
UpdateDate = convert(char(9),UpdateDate,112)+convert(char(10),UpdateDate,8), UserName = convert(char(10),UserName), type
from trigtest_au

TableName PK FieldName OldValue NewValue UpdateDate UserName type
———— —— —————- ——————– ——————– ——————- ———- —-
trigtest 1|1 i_int_key NULL 1 20030330 04:00:14 sa I
trigtest 1|1 j_int_key NULL 1 20030330 04:00:14 sa I
trigtest 1|1 s_varchar NULL hello 20030330 04:00:14 sa I
trigtest 1|1 t_char NULL goodbye 20030330 04:00:14 sa I
trigtest 1|1 d_date NULL 20000101 00:00:00 20030330 04:00:14 sa I
trigtest 2|1 i_int_key NULL 2 20030330 04:00:14 sa I
trigtest 2|1 j_int_key NULL 1 20030330 04:00:14 sa I
trigtest 2|1 s_varchar NULL hello 20030330 04:00:14 sa I
trigtest 2|1 t_char NULL goodbye 20030330 04:00:14 sa I
trigtest 2|1 d_date NULL 20000101 00:00:00 20030330 04:00:14 sa I
trigtest 1|1 s_varchar hello helloupd 20030330 04:00:14 sa U
trigtest 1|1 t_char goodbye goodbyeupd 20030330 04:00:14 sa U
trigtest 1|1 d_date 20000101 00:00:00 20000102 00:00:00 20030330 04:00:14 sa U
trigtest 1|1 t_char goodbyeupd NULL 20030330 04:00:14 sa U
trigtest 1|1 d_date 20000102 00:00:00 NULL 20030330 04:00:14 sa U
trigtest 1|1 t_char NULL good 20030330 04:00:14 sa U
trigtest 1|1 d_date NULL 20000103 00:00:00 20030330 04:00:14 sa U
trigtest 1|1 i_int_key 1 NULL 20030330 04:00:14 sa D
trigtest 1|1 j_int_key 1 NULL 20030330 04:00:14 sa D
trigtest 1|1 s_varchar helloupd NULL 20030330 04:00:14 sa D
trigtest 1|1 t_char good NULL 20030330 04:00:14 sa D
trigtest 1|1 d_date 20000103 00:00:00 NULL 20030330 04:00:14 sa D

Generic audit trail trigger Author Nigel Rivett

星期四, 四月 29th, 2010

Sql Server. Generic audit trail trigger – Author Nigel Rivett

Generic audit trail trigger
Author Nigel Rivett

/*
This trigger audit trails all changes made to a table.
It will place in the table Audit all inserted, deleted, changed columns in the table on which it is placed.
It will put out an error message if there is no primary key on the table
You will need to change @TableName to match the table to be audit trailed
*/

–Set up the tables
if exists (select * from sysobjects where id = object_id(N’[dbo].[Audit]‘) and OBJECTPROPERTY(id, N’IsUserTable’) = 1)
drop table [dbo].[Audit]
go
create table Audit (Type char(1), TableName varchar(128), PK varchar(1000), FieldName varchar(128), OldValue varchar(1000), NewValue varchar(1000), UpdateDate datetime, UserName varchar(128))
go
if exists (select * from sysobjects where id = object_id(N’[dbo].[trigtest]‘) and OBJECTPROPERTY(id, N’IsUserTable’) = 1)
drop table [dbo].[trigtest]
go
create table trigtest (i int not null, j int not null, s varchar(10), t varchar(10))
go
alter table trigtest add constraint pk primary key (i, j)
go

create trigger tr_trigtest on trigtest for insert, update, delete
as

declare @bit int ,
@field int ,
@maxfield int ,
@char int ,
@fieldname varchar(128) ,
@TableName varchar(128) ,
@PKCols varchar(1000) ,
@sql varchar(2000),
@UpdateDate varchar(21) ,
@UserName varchar(128) ,
@Type char(1) ,
@PKSelect varchar(1000)

select @TableName = ‘trigtest’

– date and user
select @UserName = system_user ,
@UpdateDate = convert(varchar(8), getdate(), 112) + ‘ ‘ + convert(varchar(12), getdate(), 114)

– Action
if exists (select * from inserted)
if exists (select * from deleted)
select @Type = ‘U’
else
select @Type = ‘I’
else
select @Type = ‘D’

– get list of columns
select * into #ins from inserted
select * into #del from deleted

– Get primary key columns for full outer join
select @PKCols = coalesce(@PKCols + ‘ and’, ‘ on’) + ‘ i.’ + c.COLUMN_NAME + ‘ = d.’ + c.COLUMN_NAME
from INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk ,
INFORMATION_SCHEMA.KEY_COLUMN_USAGE c
where pk.TABLE_NAME = @TableName
and CONSTRAINT_TYPE = ‘PRIMARY KEY’
and c.TABLE_NAME = pk.TABLE_NAME
and c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME

– Get primary key select for insert
select @PKSelect = coalesce(@PKSelect+’+',』) + 』’<’ + COLUMN_NAME + ‘=』+convert(varchar(100),coalesce(i.’ + COLUMN_NAME +’,d.’ + COLUMN_NAME + ‘))+』>』’
from INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk ,
INFORMATION_SCHEMA.KEY_COLUMN_USAGE c
where pk.TABLE_NAME = @TableName
and CONSTRAINT_TYPE = ‘PRIMARY KEY’
and c.TABLE_NAME = pk.TABLE_NAME
and c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME

if @PKCols is null
begin
raiserror(‘no PK on table %s’, 16, -1, @TableName)
return
end

select @field = 0, @maxfield = max(ORDINAL_POSITION) from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @TableName
while @field < @maxfield
begin
select @field = min(ORDINAL_POSITION) from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @TableName and ORDINAL_POSITION > @field
select @bit = (@field – 1 )% 8 + 1
select @bit = power(2,@bit – 1)
select @char = ((@field – 1) / 8) + 1
if substring(COLUMNS_UPDATED(),@char, 1) & @bit > 0 or @Type in (‘I’,'D’)
begin
select @fieldname = COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @TableName and ORDINAL_POSITION = @field
select @sql = ‘insert Audit (Type, TableName, PK, FieldName, OldValue, NewValue, UpdateDate, UserName)’
select @sql = @sql + ‘ select 』’ + @Type + 』』
select @sql = @sql + ‘,』’ + @TableName + 』』
select @sql = @sql + ‘,’ + @PKSelect
select @sql = @sql + ‘,』’ + @fieldname + 』』
select @sql = @sql + ‘,convert(varchar(1000),d.’ + @fieldname + ‘)’
select @sql = @sql + ‘,convert(varchar(1000),i.’ + @fieldname + ‘)’
select @sql = @sql + ‘,』’ + @UpdateDate + 』』
select @sql = @sql + ‘,』’ + @UserName + 』』
select @sql = @sql + ‘ from #ins i full outer join #del d’
select @sql = @sql + @PKCols
select @sql = @sql + ‘ where i.’ + @fieldname + ‘ <> d.’ + @fieldname
select @sql = @sql + ‘ or (i.’ + @fieldname + ‘ is null and d.’ + @fieldname + ‘ is not null)’
select @sql = @sql + ‘ or (i.’ + @fieldname + ‘ is not null and d.’ + @fieldname + ‘ is null)’
exec (@sql)
end
end
go

insert trigtest select 1,1,’hi’, ‘bye’
insert trigtest select 2,2,’hi’, ‘bye’
insert trigtest select 3,3,’hi’, ‘bye’
select * from Audit
select * from trigtest
update trigtest set s = ‘hibye’ where i <> 1
update trigtest set s = ‘bye’ where i = 1
update trigtest set s = ‘bye’ where i = 1
update trigtest set t = ‘hi’ where i = 1
select * from Audit
select * from trigtest
delete trigtest
select * from Audit
select * from trigtest

go
drop table Audit
go
drop table trigtest
go

需求規格書撰寫指引

星期四, 四月 29th, 2010

需求規格書撰寫指引 @ 感性與理性 :: Xuite日誌

需求規格書撰寫指引
基本概念

1. 顧客至上 — 所有的系統功能都是因為要滿足使用者或是開發者的需求。
2. 客戶的需求 = 系統要提供的功能
3. 唯有清楚的描述需求,我們才有設計的依據。
4. 需求分為兩種,使用者需求與系統需求。前者是由客戶端提出來的,比較抽象; 後者是與開發端討論過的,是完整的 、 經過可性評估的 、可作為後續設計的依據 、使用者確認過的 、加上系統觀點的。
5. SRS (System Requirement Specification)的內容主要以系統需求為主。
6. 需求的描述多半用自然語言描述,但可以輔以模組語言,例如 UML 的 use case modeling, class diagram等。
7. SRS 與 SDD 要分開,SRS 交代系統的 WHAT (系統提供什麼功能?) ,SDD 交代系統的 HOW (我們如何提供這些功能?)。

規格書內容

o 1 Introduction (Section 1 of the SRS) 簡介
+ 1.1 Purpose (1.1 of the SRS) 系統要達成的目標
+ 1.2 Scope (1.2 of the SRS) 主系統與各項子系統
+ 1.3 Definitions, acronyms, and abbreviations (1.3 of the SRS) 定義文件中使用的技術性字詞
# E.g. IIR-001:內部介面需求 (Internal Interface 5.1.4 References (1.4 of the SRS) 參考文件
+ 1.4 References (1.4 of the SRS) 參考文件
+ 1.5 Overview (1.5 of the SRS) 簡述系統的功能與大綱
o 2 Overall description (Section 2 of the SRS) 全部描述
+ 2.1 Product perspective (2.1 of the SRS) 產品概述
# a)系統界面
# b)用戶界面
# c)硬體界面
# d)軟體界面
# e)通信界面
# f)記憶
# g)行為
# h)場所適應需求
+ 2.2 Product functions (2.2 of the SRS) 產品功能
# 用文字或圖表的方法來表現不同的功能和他們的關係
# 系統所提供的功能描述必須淺顯易懂,讓第一次閱讀的人也能了解。
+ 2.3 User characteristics (2.3 of the IEEE-830) 客製化
# SRS的這個分部應該描述這種產品的用戶,有那些一般的特性,包括教育水準,經驗和技術專門技能。
# E.g.
* 人事管理員
o (1) 維護與輸入各種單據
o (2) 假單與出缺勤判讀作業
o (3) 報表列印
* 一般使用者人
o (1) 假單輸入與查詢
o (2) 打卡資料輸入
+ 2.4 Constraints (2.4 of the IEEE-830) 限制
# a)規章的政策
# b)硬體限制(例如,顯著計時要求)
# c)聯接其他應用程式介面
# d)平行操作
# e)偵錯功能
# f)控制操作
# g)高優先權的要求
# h) Signal handshake protocols(例如 XON-XOFF、ACK-NACK)
# i)可靠性需求
# j)臨界的應用
# k)安全考量。
+ 2.5 Assumptions and dependencies (2.5 of the SRS) 假設與依賴性
# SRS的這個分部應該列舉影響在SRS裡說明的要求的每個元素。這些元素不設計在軟體上的限制條件,但是能影響他們在SRS裡的要求。
# 如假定系統需用到某一作業系統的資源,但某些作業系統不提供,則SRS的需求就必須改變。
+ 2.6 Apportioning of requirements (2.6 of the SRS) 需求分配
# 記錄少分部SRS需求功能可能在未來新的版本中可能被實現。
# 一次要做出所有的功能,會花費太多時間,目前許多公司都用此方法發展軟體。
o 3 Specific requirements (Section 3 of the SRS) 特殊需求
+ 3.1 External interfaces 功能介面
# 系統輸入、輸出的詳細描述,如輸入的來源或輸出的地方、有效的範圍、容錯…。
# E.g
* EIR-002 由GDM須提供使用者界面讓使用者透過鍵盤、滑鼠直接操作本系統。
+ 3.2 Functions 功能性需求
# 負責處理輸入資料,和產生輸出。
# E.g.
* FNR-001 本系統提供員工基本資料與代碼的管理功能。[GDM 1.1.0]
* FNR-002 本系統提供對行事曆及班表的管理功能。[TAM 1.2.0]
+ 3.3 Performance requirements 效能需求 (非功能性需求)
# 記錄系統的效能
# 如 95% 的傳輸處理程序在1秒內完成。
+ 3.4 Logical database requirements 邏輯資料庫需求
# 邏輯資料的需求,如各功能使用的訊息的類型
+ 3.5 Design constraints 設計限制
# 設計的限制,如硬體的限制
+ 3.6 Software system attributes 軟體系統的屬性
# Reliability 可靠性
# Availability 可行性
# Security 安全性
# Maintainability 可維護性
# Portability 可移植性
+ 3.7 Organizing the specific requirements 組織的特別需求
+ 3.8 Additional comments 附註
o 4 Supporting information
+ 4.1 Table of contents and index
+ 4.2 Appendixes 附件,一些範本

你可以參考 IEEE Std 的標準來寫計畫書。以下為此標準的 outline。

* * 的部分表示大學部專題可以跳過不寫
* # 表由本實驗室或資工系規範,學生可暫時跳過不寫。

* 4. Considerations for producing a good SRS 考慮好的 SRS產出
o 4.3 Characteristics of a good SRS 的特色
+ 4.3.1 Correct 正確性
# 每 一項需求都必須準確地陳述其要開發的功能。做出正確判斷的參考是需求的來源,如用戶或高層的系統需求規格說明。若軟體需求與對應的系統需求相抵觸則是不正 確的。只有用戶代表才能確定用戶需求的正確性,這就是一定要有用戶的積極參與的原因。沒有用戶參與的需求評審將導致此類說法:“那些毫無意義,這些才很可 能是他們所要想的。”其實這完全是評審者憑空猜測。
+ 4.3.2 Unambiguous 明確性
# 所有需求說明的讀者都只能有一個明確統一的解釋,由於自然語言極易導致二義性,所以儘量把每項需求用簡潔明瞭的用戶性的語言表達出來。避免二義性的有效方法包括對需求文檔的正規審查,編寫測試用例,開發原型以及設計特定的方案腳本。
+ 4.3.3 Complete 完整性
# 一項需求都必須將所要實現的功能描述清楚,以使開發人員獲得設計和實現這些功能所需的所有必要資訊。
+ 4.3.4 Consistent 一致性
# 一致性是指與其他軟體需求或高層(系統,業務)需求不相矛盾。在開發前必須解決所有需求間的不一致部分。只有進行一番調查研究,才能知道某一項需求是否確實正確。
+ 4.3.5 Ranked for importance and/or stability 重要性和穩定性的排序
# 每項需求、特性或使用實例分配一個實施優先順序以指明它在特定產品中所占的分量。如果把所有的需求都看作同樣重要,那麼專案管理者在開發或節省預算或調度中就喪失控制
+ 4.3.6 Verifiable 可驗証性
# 查一下每項需求是否能通過設計測試用例或其他的驗證方法,如用演示、檢測等來確定產品是否確實按需求實現了。如果需求不可驗證,則確定其實施是否正確就成為主觀臆斷,而非客觀分析了。一份前後矛盾,不可行或有二義性的需求也是不可驗證的。
+ 4.3.7 Modifiable 可修正性
# 必 要時或為維護每一需求變更歷史記錄時,應該修訂 S R S 。這就要求每項需求要獨立標出,並與別的需求區別開來,從而無二義性。每項需求只應在 S R S 中出現一次。這樣更改時易於保持一致性。另外,使用目錄表、索引和相互參照列表方法將使軟體需求規格說明更容易修改。
+ 4.3.8 Traceable 可追縱性
# 能在每項軟體需求與它的根源和設計元素、原始碼、測試用例之間建立起鏈結鏈,這種可跟蹤性要求每項需求以一種結構化的,粒度好( f i n e – g r a i n e d )的方式編寫並單獨標明,而不是大段大段的?述。
o 4.4 Joint preparation of the SRS 開發者與客戶間共同的準備工作
o 4.5 SRS evolution SRS發展進度
o 4.6 Prototyping 原型創建
o 4.7 Embedding design in the SRS SRS的嵌入式設計
+ 4.7.1 Necessary design requirements 必要設計需求
o 4.8 Embedding project requirements in the SRS 嵌入式專案需求的SRS

本文轉自:http://140.134.26.20/~nien/CapStone/template/SRS_Guide.htm

軟體品質協會電子報

星期四, 四月 29th, 2010

軟體品質協會電子報

軟體品質協會電子報

如何撰寫需求規格書

Photo Xpress

星期三, 四月 14th, 2010

free photos
PhotoXpress

Free Icons

星期二, 四月 13th, 2010

Construction Icons | Download Objects Icons PNG icon pack | IconsPedia

JOCR – Free OCR ( chinese )

星期四, 四月 8th, 2010

JExplorer Website Powered by Woo Sik Jung

Blogspot templates

星期四, 四月 8th, 2010

Blogger Templates – Part 5

FlippingBook ordering page

星期四, 四月 8th, 2010

Page-Flip.com – FlippingBook ordering page

FlippingBook

星期四, 四月 8th, 2010

FlippingBook page flip software – create online flip book, digital edition, magazine, brochure or catalog