Giáo trình SQL Server 2005 (Phần 2)
Bạn đang xem 20 trang mẫu của tài liệu "Giáo trình SQL Server 2005 (Phần 2)", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
Tài liệu đính kèm:
- giao_trinh_sql_server_2005_phan_2.pdf
Nội dung text: Giáo trình SQL Server 2005 (Phần 2)
- 4 Ngôn ngữ định nghĩa dữ liệu – DDL Trong chương này sẽ đề cập đến nhóm các câu lệnh được sử dụng để định nghĩa và quản lý các đối tượng CSDL như bảng, khung nhìn, chỉ mục, và được gọi là ngôn ngữ định nghĩa dữ liệu (DDL). Về cơ bản, ngôn ngữ định nghĩa dữ liệu bao gồm các lệnh: CREATE: định nghĩa và tạo mới đối tượng CSDL. ALTER: thay đổi định nghĩa của đối tượng CSDL. DROP: Xoá đối tượng CSDL đã có. 4.1 Tạo bảng Câu lệnh CREATE TABLE được sử dụng để định nghĩa một bảng dữ liệu mới trong CSDL. Khi định nghĩa một bảng dữ liệu mới, ta cần phải xác định được các yêu cầu sau đây: Bảng mới được tạo ra sử dụng với mục đích gì và có vai trò như thế nào trong cơ sở dữ liệu. Cấu trúc của bảng bao gồm những trường (cột) nào, mỗi một trường có ý nghĩa như thế nào trong việc biểu diễn dữ liệu, kiểu dữ liệu của mỗi trường là gì và trường đó có cho phép nhận giá trị NULL hay không. Những trường nào sẽ tham gia vào khóa chính của bảng. Bảng có quan hệ với những bảng khác hay không và nếu có thì quan hệ như thế nào. Trên các trường của bảng có tồn tại những ràng buộc về khuôn dạng, điều kiện hợp lệ của dữ liệu hay không; nếu có thì sử dụng ở đâu và như thế nào. Câu lệnh CREATE TABLE có cú pháp như sau CREATE TABLE tên_bảng ( tên_cột thuộc_tính_cột các_ràng_buộc [, ,tên_cột_n thuộc_tính_cột_n các_ràng_buộc_cột_n] [,các_ràng_buộc_trên_bảng] ) Tên_bảng: tuân theo quy tắc định danh, không vượt quá 128 ký tự Tên_cột: các cột trong bảng, mỗi bảng có ít nhất một cột. Thuộc_tính_cột: bao gồm kiểu dữ liệu của cột, giá trị mặc định của cột, cột có được thiết lập thuộc tính identity, cột có chấp nhận giá trị NULL hay không. Trong đó kiểu dữ liệu là thuộc tính bắt buộc. 56
- Các_ràng_buộc: gồm các ràng buộc về khuôn dạng dữ liệu ( ràng buộc CHECK) hay các ràng buộc về bào toàn dữ liệu (PRIMARY KEY, FOREIGN KEY, UNIQUE) Ví dụ: Ví dụ dưới đây tạo một bảng có tên CUSTOMERS create table customers ( customerid int identity (1,1) primary key, customername nvarchar(50) not null, address nvarchar(100 ) null , birthday datetime null, gender bit default('true') not null ) Cột customerid có kiểu dữ liệu int, được chỉ định thuộc tính identity(1,1) nghĩa là dữ liệu cột này được thêm tự động bắt đầu từ 1 và mỗi lần có dòng mới thêm vào, giá trị cột này được tăng lên 1. Cột này cũng được chỉ định làm khóa chính của bảng thông qua thuộc tính primary key Thuộc tính NULL/ NOT NULL chỉ ra rằng cột đó có chấp nhận/ không chấp nhận giá trị NULL. Cột gender được chỉ định giá trị mặc định là true nghĩa là nếu không chỉ định giá trị cho cột này thì cột này có giá trị là true Ví dụ: Thêm dòng mới vào bảng customers với giá trị truyền vào đầy đủ cho các cột insert into customers values('Nguyen Van An', '22 Nguyen Thien Thuat', '5/5/1988', 'True') Thêm dòng mới vào bảng customers sử dụng giá trị mặc định insert into customers (customername, address, birthday) values('Nguyen Van An', '22 Nguyen Thien Thuat', '5/5/1988') Thêm dòng mới vào bảng customers và không truyền giá trị cho các cột cho phép giá trị NULL insert into customers (customername ) values('Nguyen Van An') 57
- 4.2 Các loại ràng buộc 4.2.1 Ràng buộc CHECK Ràng buộc CHECK được sử dụng nhằm chỉ định điều kiện hợp lệ đối với dữ liệu. Mỗi khi có sự thay đổi dữ liệu trên bảng (INSERT, UPDATE), những ràng buộc này sẽ được sử dụng nhằm kiểm tra xem dữ liệu mới có hợp lệ hay không. Ràng buộc CHECK được khai báo theo cú pháp như sau: [CONSTRAINT tên_ràng_buộc] CHECK (điều_kiện) Ví dụ: create table students ( studentid int identity(1,1) primary key, studentname nvarchar(50) not null, address nvarchar(100) not null, score1 tinyint not null constraint chk_score1 CHECK (score1 >= 0 and score1 <= 10), score2 tinyint not null constraint chk_score2 CHECK (score2 between 0 and 10), score3 tinyint not null constraint chk_score3 CHECK (score3 in (1,2,3,4,5,6,7,8,9,10)), ) Thực hiện việc thêm một dòng có dữ liệu không thỏa điều kiện insert into students values('Nguyen Van Dung', '12 Tran Quang Khai', 10, 10, -2) Có thể gộp chung các ràng buộc CHECK lại trong một ràng buộc duy nhất như sau create table students ( studentid int identity(1,1) primary key, studentname nvarchar(50) not null, address nvarchar(100) not null, score1 tinyint not null , score2 tinyint not null, 58
- score3 tinyint not null, constraint chk_score CHECK( (score1>= 0 and score1 <=10) and (score2 between 0 and 10) and (score3 in (1,2,3,4,5,6,7,8,9,10))) ) 4.2.2 Ràng buộc PRIMARY KEY Ràng buộc PRIMARY KEY được sử dụng để định nghĩa khoá chính của bảng. Khoá chính của một bảng là một hoặc một tập nhiều cột mà giá trị của chúng là duy nhất trong bảng. Hay nói cách khác, giá trị của khoá chính sẽ giúp cho ta xác định được duy nhất một dòng (bản ghi) trong bảng dữ liệu. Mỗi một bảng chỉ có thể có duy nhất một khoá chính và bản thân khoá chính không chấp nhận giá trị NULL. Ràng buộc PRIMARY KEY là cơ sở cho việc đảm bảo tính toàn vẹn thực thể cũng như toàn vẹn tham chiếu. Để khai báo một ràng buộc PRIMARY KEY, ta sử dụng cú pháp như sau: [CONSTRAINT tên_ràng_buộc] PRIMARY KEY [(danh_sách_cột)] Nếu khoá chính của bảng chỉ bao gồm đúng một cột và ràng buộc PRIMARY KEY được chỉ định ở mức cột, ta không cần thiết phải chỉ định danh sách cột sau từ khoá PRIMARY KEY. Tuy nhiên, nếu việc khai báo khoá chính được tiến hành ở mức bảng (sử dụng khi số lượng các cột tham gia vào khoá là từ hai trở lên) thì bắt buộc phải chỉ định danh sách cột ngay sau từ khóa PRIMARY KEY và tên các cột được phân cách nhau bởi dấu phẩy. Ví dụ 1: Định nghĩa một bảng chỉ có một khóa chính create table customers ( customerid int identity(1,2) constraint chk_primarykey primary key, customername nvarchar(50) not null, address nvarchar(100) not null, gender bit not null ) Hoặc là create table customers ( customerid int identity(1,2) primary key, customername nvarchar(50) not null, 59
- address nvarchar(100) not null, gender bit not null ) Ví dụ 2: Định nghĩa bảng có hai khóa chính: create table orderdetail ( customerid int, orderid int, itemid int not null, quantity decimal(8,2) not null, constraint chk_primarykey primary key (customerid, orderid) ) 4.2.3 Ràng buộc FOREIGN KEY FOREIGN KEY là một cột hay một sự kết hợp của nhiều cột được sử dụng để áp đặt mối liên kết dữ liệu giữa hai table. FOREIGN KEY của một bảng sẽ giữ giá trị của PRIMARY KEY của một bảng khác và chúng ta có thể tạo ra nhiều FOREIGN KEY trong một table. FOREIGN KEY có thể tham chiếu vào PRIMARY KEY hay cột có ràng buộc duy nhất. FOREIGN KEY có thể chứa giá trị NULL. Mặc dù mục đích chính của ràng buộc FOREIGN KEY là để kiểm soát dữ liệu chứa trong bảng có FOREIGN KEY (tức table con) nhưng thực chất nó cũng kiểm soát luôn cả dữ liệu trong bảng chứa PRIMARY KEY (tức table cha). Ví dụ nếu ta xóa dữ liệu trong bảng cha thì dữ liệu trong bảng con trở nên "mồ côi" (orphan) vì không thể tham chiếu ngược về bảng cha. Do đó ràng buộc FOREIGN KEY sẽ đảm bảo điều đó không xảy ra. Nếu bạn muốn xóa dữ liệu trong bảng cha thì trước hết bạn phải xóa hay vô hiệu hóa ràng buộc FOREIGN KEY trong bảng con trước. Ràng buộc FOREIGN KEY được định nghĩa theo cú pháp dưới đây: [CONSTRAINT tên_ràng_buộc] FOREIGN KEY [(danh_sách_cột)] REFERENCES tên_bảng_tham_chiếu(danh_sách_cột_tham_chiếu) [ON DELETE CASCADE | NO ACTION | SET NULL | SET DEFAULT] [ON UPDATE CASCADE | NO ACTION | SET NULL | SET DEFAULT] Việc định nghĩa một ràng buộc FOREIGN KEY bao gồm các yếu tố sau: Tên cột hoặc danh sách cột của bảng được định nghĩa tham gia vào khoá ngoài. Tên của bảng được tham chiếu bởi khoá ngoài và danh sách các cột được tham chiếu đến trong bảng tham chiếu. 60
- Cách thức xử lý đối với các bản ghi trong bảng được định nghĩa trong trường hợp các bản ghi được tham chiếu trong bảng tham chiếu bị xoá (ON DELETE) hay cập nhật (ON UPDATE). SQL chuẩn đưa ra 4 cách xử lý CASCADE: Tự động xoá (cập nhật) nếu bản ghi được tham chiếu bị xoá (cập nhật). NO ACTION: (Mặc định) Nếu bản ghi trong bảng tham chiếu đang được tham chiếu bởi một bản ghi bất kỳ trong bảng được định nghĩa thì bàn ghi đó không được phép xoá hoặc cập nhật (đối với cột được tham chiếu). SET NULL: Cập nhật lại khoá ngoài của bản ghi thành giá trị NULL (nếu cột cho phép nhận giá trị NULL). SET DEFAULT: Cập nhật lại khoá ngoài của bản ghi nhận giá trị mặc định (nếu cột có qui định giá trị mặc định). Ví dụ: drop table orderdetail create table orderdetail ( orderid int constraint fk_orderdetail_orders foreign key references orders(orderid) on delete cascade on update cascade, customerid int constraint fk_orderdetail_customer foreign key references customers(customerid) on delete cascade on update cascade, itemid int constraint fk_orderdetail_items foreign key references items(itemid) on delete cascade on update cascade, quantity decimal(18,2) not null, ) 4.3 Sửa đổi định nghĩa bảng Một bảng sau khi đã được định nghĩa bằng câu lệnh CREATE TABLE có thể được sửa đổi thông qua câu lệnh ALTER TABLE. Câu lệnh này cho phép thực hiện được các thao tác sau: Bổ sung một cột vào bảng. 61
- Xoá một cột khỏi bảng. Thay đổi định nghĩa của một cột trong bảng. Xoá bỏ hoặc bổ sung các ràng buộc cho bảng Cú pháp của câu lệnh ALTER TABLE như sau: ALTER TABLE tên_bảng ADD định_nghĩa_cột | ALTER COLUMN tên_cột kiểu_dữ_liệu [NULL | NOT NULL] DROP COLUMN tên_cột | ADD CONSTRAINT tên_ràng_buộc định_nghĩa_ràng_buộc DROP CONSTRAINT tên_ràng_buộc Ví dụ 1: Thêm một cột mới vào bảng ORDERS alter table orders add description nvarchar(100) not null Ví dụ 2: Thay đổi định nghĩa cột desciption alter table orders alter column description nvarchar(200) null Ví dụ 3: Thêm ràng buộc CHECK vào cột decription alter table orders add constraint chk_descriptionlength CHECK (len(description) > 10) Ví dụ 4: Xóa ràng buộc CHECK alter table orders drop chk_descriptionlength Ví dụ 5: Xóa cột description alter table orders drop column description Ví dụ 6: Thêm một cột mới vào bảng orders và thêm ràng buộc cho cột này alter table orders add description nvarchar(100) null, constraint chk_descriptionlength CHECK (len(description) > 0) Nếu bổ sung thêm một cột vào bảng và trong bảng đã có ít nhất một bản ghi thì cột mới cần bổ sung phải cho phép chấp nhận giá trị NULL hoặc phải có giá trị mặc định. Muốn xoá một cột đang được ràng buộc bởi một ràng buộc hoặc đang được tham chiếu bởi một khoá ngoài, ta phải xoá ràng buộc hoặc khoá ngoài trước sao cho trên cột không còn bất kỳ một ràng buộc và không còn được tham chiếu bởi bất kỳ khoá ngoài nào. 62
- Nếu bổ sung thêm ràng buộc cho một bảng đã có dữ liệu và ràng buộc cần bổ sung không được thoả mãn bởi các bản ghi đã có trong bảng thì câu lệnh ALTER TABLE không thực hiện được. 4.4 Xóa bảng Khi một bảng không còn cần thiết , ta có thể xoá nó ra khỏi cơ sở dữ liệu bằng câu lệnh DROP TABLE. Câu lệnh này cũng đồng thời xoá tất cả những ràng buộc, chỉ mục, trigger liên quan đến bảng đó. Câu lệnh có cú pháp như sau: DROP TABLE tên_bảng Trong các hệ quản trị cơ sở dữ liệu, khi đã xoá một bảng bằng lệnh DROP TABLE, ta không thể khôi phục lại bảng cũng như dữ liệu của nó. Do đó, cần phải cẩn thận khi sử dụng câu lệnh này. Câu lệnh DROP TABLE không thể thực hiện được nếu bảng cần xoá đang được tham chiếu bởi một ràng buộc FOREIGN KEY. Trong trường hợp này, ràng buộc FOREIGN KEY đang tham chiếu hoặc bảng đang tham chiếu đến bảng cần xoá phải được xoá trước. Khi một bảng bị xoá, tất cả các ràng buộc, chỉ mục và trigger liên quan đến bảng cũng đồng thời bị xóa theo. Do đó, nếu ta tạo lại bảng thì cũng phải tạo lại các đối tượng này. Ví dụ: Để xóa bảng ORDERS trước tiên ta phải xóa ràng buộc FOREIGN KEY từ bảng ORDERDETAIL alter table orderdetail drop constraint fk_orderdetail_orders Sau đó xóa bảng ORDERS drop table orders 4.5 Khung nhìn - VIEW Khung nhìn là một bảng tạm thời, có cấu trúc như một bảng, khung nhìn không lưu trữ dữ liệu mà nó được tạo ra khi sử dụng, khung nhìn là đối tượng thuộc CSDL. Khung nhìn được tạo ra từ câu lệnh truy vấn dữ liệu (lệnh SELECT), truy vấn từ một hoặc nhiều bảng dữ liệu. Khung nhìn được sử dụng khai thác dữ liệu như một bảng dữ liệu, chia sẻ nhiều người dùng, an toàn trong khai thác, không ảnh hưởng dữ liệu gốc. Có thể thực hiện truy vấn dữ liệu trên cấu trúc của khung nhìn. 63
- Như vậy, một khung nhìn trông giống như một bảng với một tên khung nhìn và là một tập bao gồm các dòng và các cột. Điểm khác biệt giữa khung nhìn và bảng là khung nhìn không được xem là một cấu trúc lưu trữ dữ liệu tồn tại trong cơ sở dữ liệu. Thực chất dữ liệu quan sát được trong khung nhìn được lấy từ các bảng thông qua câu lệnh truy vấn dữ liệu. Câu lệnh CREATE VIEW được sử dụng để tạo ra khung nhìn và có cú pháp như sau: CREATE VIEW tên_khung_nhìn[(danh_sách_tên_cột)] AS câu_lệnh_SELECT Ví dụ: create view CUSTOMERINFO as select CUSTOMERNAME, (year(getdate()) - year(BIRTHDAY)) as AGE, ADDRESS from customers Thực hiện câu truy vấn trên khung nhìn vừa tạo ra: select * from customerinfo Nếu trong câu lệnh CREATE VIEW, ta không chỉ định danh sách các tên cột cho khung nhìn, tên các cột trong khung nhìn sẽ chính là tiêu đề các cột trong kết quả của câu lệnh SELECT. Trong trường hợp tên các cột của khung nhìn đươc chỉ định, chúng phải có cùng số lượng với số lượng cột trong kết quả của câu truy vấn. Ví dụ: create view CUSTOMERINFO (CUSTOMERNAME, AGE, ADDRESS) as select CUSTOMERNAME, year(getdate()) - year(BIRTHDAY), ADDRESS from customers Lưu ý: Phải đặt tên cho các cột của khung nhìn trong các trường hợp sau đây: 64
- Trong kết quả của câu lệnh SELECT có ít nhất một cột được sinh ra bởi một biểu thức (tức là không phải là một tên cột trong bảng cơ sở) và cột đó không được đặt tiêu đề. Tồn tại hai cột trong kết quả của câu lệnh SELECT có cùng tiêu đề cột. 4.6 Thêm, cập nhật, xóa dữ liệu trong VIEW Đối với một số khung nhìn, ta có thể tiến hành thực hiện các thao tác cập nhập, thêm và xoá dữ liệu. Thực chất, những thao tác này sẽ được chuyển thành những thao tác trên các bảng cơ sở và có tác động đến những bảng cơ sở. Về mặt lý thuyết, để có thể thực hiện thao tác bổ sung, cập nhật và xoá, một khung nhìn trước tiên phải thoả mãn các điều kiện sau đây: Trong câu lệnh SELECT định nghĩa khung nhìn không được sử dụng từ khoá DISTINCT, TOP, GROUP BY và UNION. Các thành phần xuất hiện trong danh sách chọn của câu lệnh SELECT phải là các cột trong các bảng cơ sở. Trong danh sách chọn không được chứa các biểu thức tính toán, các hàm gộp. Ngoài những điều kiện trên, các thao tác thay đổi đến dữ liệu thông qua khung nhìn còn phải đảm bảo thoả mãn các ràng buộc trên các bảng cơ sở, tức là vẫn đảm bảo tính toàn vẹn dữ liệu. Mặc dù thông qua khung nhìn có thể thực hiện được thao tác bổ sung và cập nhật dữ liệu cho bảng cơ sở nhưng chỉ hạn chế đối với những khung nhìn đơn giản. Đối với những khung nhìn phức tạp thì thường không thực hiện được; hay nói cách khác là dữ liệu trong khung nhìn là chỉ đọc. 4.7 Thay đổi định nghĩa khung nhìn Câu lệnh ALTER VIEW dùng để định nghĩa lại khung nhìn có cấu trúc như sau: ALTER VIEW tên_khung_nhìn [(danh_sách_tên_cột)] AS Câu_lệnh_SELECT Ví dụ: Ví dụ dưới đây định nghĩa lại khung nhìn CUSTOMERINFO alter view customerinfo as select CUSTOMERNAME, (year(getdate()) - year(birthday)) as AGE, ADDRESS, GENDER from customers Lưu ý: lệnh CREATE VIEW không làm thay đổi các quyền đã được cấp phát cho người sử dụng trước đó. 65
- 4.8 Xóa khung nhìn Câu lệnh DROP VIEW dùng để xóa khung nhìn có cấu trúc như sau: DROP VIEW tên_khung_nhìn Ví dụ: drop view customerinfo Lưu ý: Nếu một khung nhìn bị xoá, toàn bộ những quyền đã cấp phát cho người sử dụng trên khung nhìn cũng đồng thời bị xoá. Do đó, nếu ta tạo lại khung nhìn thì phải tiến hành cấp phát lại quyền cho người sử dụng. 66
- 5 Thủ tục lưu trữ, hàm và trigger 5.1 Thủ tục lưu trữ (Stored procedure) Thủ tục lưu trữ là một đối tượng trong CSDL, bao gồm nhiều câu lệnh T-SQL được tập hợp lại với nhau thành một nhóm, và tất cả các lệnh này sẽ được thực thi khi thủ tục lưu trữ được thực thi. Với thủ tục lưu trữ, một phần nào đó khả năng của ngôn ngữ lập trình được đưa vào trong ngôn ngữ SQL. Thủ tục lưu trữ có thể có các thành phần sau: Các cấu trúc điều khiển (IF, WHILE, FOR) có thể được sử dụng trong thủ tục. Bên trong thủ tục lưu trữ có thể sử dụng các biến như trong ngôn ngữ lập trình nhằm lưu giữ các giá trị tính toán được, các giá trị được truy xuất được từ cơ sở dữ liệu. Một tập các câu lệnh SQL được kết hợp lại với nhau thành một khối lệnh bên trong một thủ tục. Một thủ tục có thể nhận các tham số truyền vào cũng như có thể trả về các giá trị thông qua các tham số (như trong các ngôn ngữ lập trình). Khi một thủ tục lưu trữ đã được định nghĩa, nó có thể được gọi thông qua tên thủ tục, nhận các tham số truyền vào, thực thi các câu lệnh SQL bên trong thủ tục và có thể trả về các giá trị sau khi thực hiện xong. Lợi ích của việc sử dụng thủ tục lưu trữ: SQL Server chỉ biên dịch các thủ tục lưu trữ một lần và sử dụng lại kết quả biên dịch này trong các lần tiếp theo trừ khi người dùng có những thiết lập khác. Việc sử dụng lại kết quả biên dịch không làm ảnh hưởng đến hiệu suất hệ thống khi thủ tục lưu trữ được gọi liên tục nhiều lần. Thủ tục lưu trữ được phân tích, tối ưu khi tạo ra nên việc thực thi chúng nhanh hơn nhiều so với việc phải thực hiện một tập rời rạc các câu lệnh SQL tương đương theo cách thông thường. Thủ tục lưu trữ cho phép chúng ta thực hiện cùng một yêu cầu bằng một câu lệnh đơn giản thay vì phải sử dụng nhiều dòng lệnh SQL. Điều này sẽ làm giảm thiểu sự lưu thông trên mạng. Thay vì cấp phát quyền trực tiếp cho người sử dụng trên các câu lệnh SQL và trên các đối tượng cơ sở dữ liệu, ta có thể cấp phát quyền cho người sử dụng thông qua các thủ tục lưu trữ, nhờ đó tăng khả năng bảo mật đối với hệ thống. Các thủ tục lưu trữ trả về kết quả theo 4 cách: Sử dụng các tham số output Sử dụng các lệnh trả về giá trị, các lệnh này luôn trả về giá trị số nguyên. 67
- Tập các giá trị trả vể của mỗi câu lệnh SELECT có trong thủ tục lưu trữ hoặc của quá trình gọi một thủ tục lưu trữ khác trong một thủ tục lưu trữ. Một biến con trỏ toàn cục có thể tham chiếu từ bên ngoài thủ tục. 5.1.1 Tạo thủ tục lưu trữ Thủ tục lưu trữ được tạo thông qua câ.u lệnh CREATE PROCEDURE. CREATE PROCEDURE tên_thủ_tục [(danh_sách_tham_số)] [WITH RECOMPILE|ENCRYPTION|RECOMPILE,ENCRYPTION] AS Các_câu_lệnh_của_thủ_tục Trong đó: WITH RECOMPILE: yêu cầu SQL Server biên dịch lại thủ tục lưu trữ mỗi khi được gọi. WITH ENCRYPTION: yêu cầu SQL Server mã hóa thủ tục lưu trữ. Các_câu_lệnh_của_thủ_tục: Các lệnh T-SQL. Các lệnh này có thể nằm trong cặp BEGIN END hoặc không. Ví dụ: Giả sử cần thực hiện các công việc theo thứ tự như sau: Nhập một đơn đặt hàng mới của khách hàng có mã khách hàng là 3 Nhập các chi tiết đơn đặt hàng cho đơn đặt hàng trên. Để thực hiện các công việc trên chúng ta cần các câu lệnh như sau: Trước tiên nhập đơn đặt hàng cho khách hàng có mã khách hàng là 3 insert into orders values(3, '7/22/2008') Tiếp theo thêm các chi tiết đơn đặt hàng cho hóa đơn này. Giả sử rằng đơn đặt hàng có mã là 4 và khách hàng đặt một mặt hàng có mã là 1. insert into orderdetail values(4, 1, 10) Cách viết như trên có hạn chế là: trong quá trình làm việc sẽ có rất nhiều đơn đặt hàng mới, do đó người dùng sẽ phải viết đi viết lại những câu lệnh tương tự nhau cho các khách hàng khác nhau. Một cách giải quyết vấn đề này là dùng thủ tục lưu trữ và dùng tham số để nhận các thông tin thay đổi. create procedure sp_InsertOrderAndOrderDetail @customerid int, @orderdate datetime, @orderid int, @itemid int, 68
- @quantity decimal, as begin insert into orders values(@customerid, @orderdate) insert into orderdetail values(@orderid, @itemid, @quantity) end Thực hiện thủ tực lưu trữ này như sau: sp_InsertOrderAndOrderDetail ‘3’, ‘22/7/2008’, ‘4’, ‘1’, ‘10’) 5.1.2 Lời gọi thủ tục Thủ tục lưu trữ được gọi theo cấu trúc Tên_thủ_tục_lưu _trữ [danh_sách_tham_số] Cần lưu ý là danh sách tham số truyền vào trong lời gọi phải theo đúng thứ tự khai báo các tham số trong thủ tục lưu trữ. Nếu thủ tục được gọi từ một thủ tục khác, thực hiện bên trong một trigger hay phối hợp với câu lệnh SELECT, cấu trúc như sau; Exec Tên_thủ_tục_lưu _trữ [danh_sách_tham_số] 5.1.3 Biến trong thủ tục lưu trữ Trong thủ tục lưu trũ có thể có các biến nhằm lưu các kết quả tính toán hay truy xuất từ CSDL. Các biến trong thủ tục được khai báo bằng từ khóa DECLARE theo cấu trúc như sau: DECLARE @tên_biến kiểu_dữ_liệu Ví dụ: create procedure sp_SelectCustomerWithMaxAge as begin declare @maxAge int select @maxAge = max(year(getdate())-year(BIRTHDAY)) from customers select CUSTOMERNAME, BIRTHDAY from customers where year(getdate())-year(BIRTHDAY)=@maxAge 69
- end 5.1.4 Giá trị trả về trong thủ tục lưu trữ Trong các ví dụ trước, nếu đối số truyền cho thủ tục khi có lời gọi đến thủ tục là biến, những thay đổi giá trị của biền trong thủ tục sẽ không được giữ lại khi kết thúc quá trình thực hiện thủ tục. Ví dụ: Có thủ tục lưu trữ như sau create procedure sp_TestOutput @a int, @b int, @c int as select @c = @a + @b Thực thi thủ tục: Declare @tong int set @tong = 0 sp_TestOutput 100, 200, @tong select @tong Kết quả là 0. Sử dụng tham số OUTPUT Trong trường hợp cần phải giữ lại giá trị của đối số sau khi kết thúc thủ tục, ta phải khai báo tham số của thủ tục theo cú pháp như sau: @tên_tham_số kiểu_dữ_liệu OUTPUT Ví dụ trên được viết lại như sau: create procedure sp_TestOutput @a int, @b int, @c int output as select @c = @a + @b Thực thi thủ tục: Declare @tong int set @tong = 0 sp_TestOutput 100, 100, @tong output select @tong 70
- Kết quả là 200. Sử dụng lệnh RETURN Tương nhự như việc sử dụng tham số OUTPUT, câu lệnh RETURN trả về giá trị cho đối tượng thực thi stored procedure. Ví dụ: create procedure sp_TestReturn as begin declare @out int select @out = count(*) from customers return @out end Thực thi thủ tục lưu trữ declare @a int exec @a = sp_TestReturn select @a 5.1.5 Tham số với giá trị mặc định Các tham số được khai báo trong thủ tục có thể nhận các giá trị mặc định. Giá trị mặc định sẽ được gán cho tham số trong trường hợp không truyền đối số cho tham số khi có lời gọi đến thủ tục. Tham số với giá trị mặc định được khai báo theo cú pháp như sau: @tên_tham_sốkiểu_dữ_liệu = giá_trị_mặc_định Ví dụ: create procedure sp_TestDefault @customerid int = 3 as begin select * from customers where customerid = @customerid end Thực thi thủ tục lưu trữ theo giá trị mặc định của tham số. sp_TestDefault 71
- Thực thi thủ tục và truyền giá trị cho tham số: sp_TestDefault 4 5.1.6 Sửa đổi thủ tục Khi một thủ tục đã được tạo ra, ta có thể tiến hành định nghĩa lại thủ tục đó bằng câu lệnh ALTER PROCEDURE có cú pháp như sau: ALTER PROCEDURE tên_thủ_tục [(danh_sách_tham_số)] [WITH RECOMPILE|ENCRYPTION|RECOMPILE,ENCRYPTION] AS Các_câu_lệnh_của_thủ_tục Câu lệnh này sử dụng tương tự như câu lệnh CREATE PROCEDURE. Việc sửa đổi lại một thủ tục đã có không làm thay đổi đến các quyền đã cấp phát trên thủ tục cũng như không tác động đến các thủ tục khác hay trigger phụ thuộc vào thủ tục này. 5.1.7 Xóa thủ tục Để xoá một thủ tục đã có, ta sử dụng câu lệnh DROP PROCEDURE với cú pháp như sau: DROP PROCEDURE tên_thủ_tục Khi xoá một thủ tục, tất cả các quyền đã cấp cho người sử dụng trên thủ tục đó cũng đồng thời bị xoá bỏ. Do đó, nếu tạo lại thủ tục, ta phải tiến hành cấp phát lại các quyền trên thủ tục đó. 5.2 Hàm do người dùng định nghĩa (User Defined Function-UDF) Hàm do người dùng định nghĩa được chia làm 3 loại: (1) scalar (hàm vô hướng), (2) inline table-valued (hàm nội tuyến, giá trị trả về dạng bảng), (3) multi-statement table-valued (hàm bao gồm nhiều câu lệnh SQL bên trong, trả về giá trị dạng bảng) Scalar UDF: được sử dụng để trả về một duy nhất một giá trị dựa trên một các tham số truyền vào. Ví dụ: ta có thể tạo ra một UDF vô hướng nhận Customerid là tham số và trả về CustomerName. Inline table-valued: trả về một bảng dựa trên một câu lệnh SQL duy nhất định nghĩa các dòng và các cột trả về. 72
- Multi-statement table-value: cũng trả về kết quả là một tập hợp nhưng có thể dựa trên nhiều câu lệnh SQL. 5.2.1 Hàm vô hướng - Scalar UDF Scarlar UDF được tạo ra bằng câu lệnh CREATE FUNCTION có cấu trúc như sau; CREATE FUNCTION tên_hàm ([danh_sách_tham_số]) RETURNS (kiểu_trả_về_của_hàm) AS BEGIN các_câu_lệnh_của_hàm END Ví dụ: Câu lệnh dưới đây định nghĩa hàm tính ngày trong tuần (thứ trong tuần) của một giá trị kiểu ngày create function f_ thu(@ngay datetime) returns nvarchar(10) as begin declare @st nvarchar(10) select @st=case datepart(dw,@ngay) when 1 then N'chủ nhật' when 2 then N'thứ hai' when 3 then N 'thứ ba' when 4 then N 'thứ tư' when 5 then N 'thứ năm' when 6 then N 'thứ sáu' else N 'thứ bảy' end return (@st) /* trị trả về của hàm */ end Sau khi chạy thành công, hàm trở thành một đối tượng trong CSDL và có thể được truy xuất như các hàm được xây dựng sẵn trong SQL Server 2005 Express Edition. 73
- Ví dụ: select CUSTOMERNAME, dbo.f_thu(BIRTHDAY) from customers 5.2.2 Hàm nội tuyến - Inline UDF Hàm nội tuyến được định nghĩa bằng lệnh CREATE FUNCTION. CREATE FUNCTION tên_hàm ([danh_sách_tham_số]) RETURNS TABLE AS RETURN (câu_lệnh_select) Cú pháp của hàm nội tuyến phải tuân theo các qui tắc sau: Kiểu trả về của hàm phải được chỉ định bởi mệnh đề RETURNS TABLE. 74
- Trong phần thân của hàm chỉ có duy nhất một câu lệnh RETURN xác định giá trị trả về của hàm thông qua duy nhất một câu lệnh SELECT. Ngoài ra, không sử dụng bất kỳ câu lệnh nào khác trong phần thân của hàm. Ví dụ: Ví dụ dưới đây lấy ra các khách hàng tùy thuộc vào giá trị mã khách hàng truyền vào cho tham số. create function f_SelectCustomer (@customerid int) returns table as return (select * from customers where customerid > @customerid) Việc gọi các hàm nội tuyến cũng tương tự như việc gọi các hàm vô hướng. Ví dụ: select tmp.CUSTOMERNAME, o.ORDERDATE from orders o inner join dbo.f_SelectCustomer(3) as tmp on o.customerid = tmp.customerid 5.2.3 Hàm bao gồm nhiều câu lệnh bên trong – Multi statement UDF Hàm này cũng được định nghĩa bằng lệnh CREATE FUNCTION CREATE FUNCTION tên_hàm ([danh_sách_tham_số]) RETURNS @biến_bảng TABLE định_nghĩa_bảng AS BEGIN các_câu_lệnh_trong_thân_hàm RETURN END Lưu ý: sau từ khóa RETURNS là một biến bảng được định nghĩa. Và sau từ khóa RETURN ở cuối hàm không có tham số nào đi kèm. Ví dụ: create function f_SelectCustomer (@customerid int) returns @myCustomers table ( customerid int, 75
- customername nvarchar(50), orderdate datetime ) as begin if @customerid = 0 insert into @myCustomers select c.customerid, c.customername, o.orderdate from customers c inner join orders o on o.customerid = c.customerid else insert into @myCustomers select c.customerid, c.customername, o.orderdate from customers c inner join orders o on c.customerid = o.customerid where c.customerid = @customerid return end Việc gọi hàm multi statement UDF cũng tương tự các loại hàm khác select * from f_SelectCustomer(0) select * from f_SelectCustomer(3) 5.2.4 Thay đổi hàm Dùng lệnh ALTER FUNCTION để thay đổi định nghĩa hàm. Cấu trúc của câu lệnh ALTER FUNCTION tương tự như CREATE FUNCTION Ví dụ: alter function f_SelectCustomer (@customerid int) returns table as return (select * from customers 76
- where customerid > @customerid) 5.2.5 Xóa hàm Dùng lệnh DROP FUNCTION để xóa hàm. Cấu trúc lệnh DROP FUNCTION như sau DROP FUNCTION tên_hàm Ví dụ: drop function f_thu Tương tự như thủ tục lưu trữ, khi hàm bị xóa các quyền cấp cho người dùng trên hàm đó cũng bị xóa. Do đó khi định nghĩa lại hàm này, ta phải cấp lại quyền cho các người dùng. 5.3 Trigger Trigger là một dạng đặc biệt của thủ tục lưu trữ, được thực thi một cách tự động khi có sự thay đổi dữ liệu (do tác động của câu lệnh INSERT, UPDATE, DELETE) trên một bảng nào đó. 5.3.1 Các đặc điểm của trigger Trigger chỉ thực thi tự động thông qua các sự kiện mà không thực hiện bằng tay. Trigger sử dụng được với khung nhìn. Khi trigger thực thi theo các sự kiện Insert hoặc Delete thì dữ liệu khi thay đổi sẽ được chuyển sang các bảng INSERTED và DELETED, là 2 bảng tạm thời chỉ chứa trong bộ nhớ, các bảng này chỉ được sử dụng với các lệnh trong trigger. Các bảng này thường được sử dụng để khôi phục lại phần dữ liệu đã thay đổi (roll back). Trigger chia thành 2 loại INSTEAD OF và AFTER: INSTEAD OF là loại trigger mà hoạt động của sự kiện gọi trigger sẽ bị bỏ qua và thay vào đó là các lệnh trong trigger được thực hiện. AFTER trigger là loại ngầm định, khác với loại INSTEAD OF thì loại trigger này sẽ thực hiện các lệnh bênh trong sau khi đã thực hiện xong sự kiện kích hoạt trigger. 5.3.2 Các trường hợp sử dụng trigger Sử dụng Trigger khi các biện pháp bảo đảm toàn vẹn dữ liệu khác không bảo đảm được. Các công cụ này sẽ thực hiện kiểm tra tính toán vẹn trước khi đưa dữ liệu vào CSDL, còn Trigger thực hiện kiểm tra tính toàn vẹn khi công việc đã thực hiện Khi CSDL chưa được chuẩn hóa (Normalization) thì có thể xảy ra dữ liệu thừa, chứa ở nhiều vị trí trong CSDL thì yêu cầu đặt ra là dữ liệu cần cập nhật thống nhất trong mọi nơi. Trong trường hợp này ta phải sử dụng Trigger. 77
- Khi xảy ra thay đổi dây chuyền dữ liệu giữa các bảng với nhau (khi dữ liệu bảng này thay đổi thì dữ liệu trong bảng khác cũng được thay đổi theo). 5.3.3 Khả năng sau của trigger Một trigger có thể nhận biết, ngăn chặn và huỷ bỏ được những thao tác làm thay đổi trái phép dữ liệu trong cơ sở dữ liệu. Các thao tác trên dữ liệu (xoá, cập nhật và bổ sung) có thể được trigger phát hiện ra và tự động thực hiện một loạt các thao tác khác trên cơ sở dữ liệu nhằm đảm bảo tính hợp lệ của dữ liệu. Thông qua trigger, ta có thể tạo và kiểm tra được những mối quan hệ phức tạp hơn giữa các bảng trong cơ sở dữ liệu mà bản thân các ràng buộc không thể thực hiện được. 5.3.4 Định nghĩa trigger Câu lệnh CREATE TRIGGER được sử dụng để đinh nghĩa trigger và có cấu trúc như sau: CREATE TRIGGER tên_trigger ON tên_bảng FOR {[INSERT][,][UPDATE][,][DELETE]} AS [IF UPDATE(tên_cột) [AND UPDATE(tên_cột)|OR UPDATE(tên_cột)] ] các_câu_lệnh_của_trigger Lưu ý: Như đã nói ở trên, chuẩn SQL định nghĩa hai bảng logic INSERTED và DELETED để sử dụng trong các trigger. Cấu trúc của hai bảng này tương tự như cấu trúc của bảng mà trigger tác động. Dữ liệu trong hai bảng này tuỳ thuộc vào câu lệnh tác động lên bảng làm kích hoạt trigger; cụ thể trong các trường hợp sau: Khi câu lệnh DELETE được thực thi trên bảng, các dòng dữ liệu bị xoá sẽ được sao chép vào trong bảng DELETED. Bảng INSERTED trong trường hợp này không có dữ liệu. Dữ liệu trong bảng INSERTED sẽ là dòng dữ liệu được bổ sung vào bảng gây nên sự kích hoạt đối với trigger bằng câu lệnh INSERT. Bảng DELETED trong trường hợp này không có dữ liệu. Khi câu lệnh UPDATE được thực thi trên bảng, các dòng dữ liệu cũ chịu sự tác động của câu lệnh sẽ được sao chép vào bảng DELETED, còn trong bảng INSERTED sẽ là các dòng sau khi đã được cập nhật. 78
- Hoạt động Bảng INSERTED Bảng DELETED INSERT dữ liệu được insert không có dữ liệu DELETE không có dữ liệu dữ liệu bị xóa UPDATE dữ liệu được cập nhật dữ liệu trước khi cập nhật Ví dụ 1: Ví dụ dưới đây minh họa việc trigger được kích hoạt khi thêm dữ liệu vào bảng CUSTOMERS if exists (select name from sysobjects where name = 't_CheckCustomerName' and type = 'TR') drop trigger t_CheckCustomerName go create trigger t_CheckCustomerName on customers for insert as declare @lengthOfName int select @lengthOfName = len(inserted.customername) from inserted if @lengthOfName <=1 print N'Tên không hợp lệ' rollback tran go Thêm một khách hàng mới có tên là A insert into customers values('A', '5/5/1978', 'True', '35 Hung Vuong') Ví dụ 2: Ví dụ dưới đây minh họa trigger được kích hoạt khi có sự thay đổi mang tính đây chuyền giữa các bảng. Giả sử có CSDL như sau: 79
- Với dữ liệu trong từng bảng là: Giả sử có một khách hàng mua 10 đơn vị mặt hàng LAPTOP. Khi đó số lượng LAPTOP trong bảng ITEMFORSALE sẽ giảm xuống còn 90. Trigger dưới đây sẽ thực hiện công việc đó. if exists (select name from sysobjects where name = 't_DecreaseQuantityOfItemForSale') drop trigger t_DecreaseQuantityOfItemForSale go create trigger t_DecreaseQuantityOfItemForSale on SALE for insert as update ITEMSFORSALE set itemsforsale.quantity = itemsforsale.quantity - inserted.salequantity from itemsforsale inner join inserted on itemsforsale.itemid = inserted.itemid go Thực hiện thêm dòng vào bảng SALE insert into sale values( 1, 10) Ví dụ 3: Ví dụ này minh họa cũng minh họa trigger được kích hoạt khi có sự thay đổi mang tính dây chuyền giữa các bảng nhưng trong trường hợp này dữ liệu thay đổi liên quan đến nhiều dòng. 80
- Giả sử người quản lý muốn thay đổi số lượng bán mặt hàng LAPTOP trong bãng SALE lên thêm 5 đơn vị. Như vậy từ kết quả ví dụ 2, ta thấy cần phải giảm số lượng LAPTOP trong bảng ITEMSFORSALE xuống 10 đơn vị. Tuy nhiên, trong thực tế khi số lượng các dòng trong bảng SALE rất lớn, khi đó phải sử dụng trigger: if exists (select name from sysobjects where name = 't_DecreaseSumQuantityOfItemForSale') drop trigger t_DecreaseSumQuantityOfItemForSale go create trigger t_DecreaseSumQuantityOfItemForSale on SALE for update as if update(salequantity) update ITEMSFORSALE set itemsforsale.quantity = itemsforsale.quantity - (select sum(inserted.salequantity - deleted.salequantity) from deleted inner join inserted on deleted.saleid = inserted.saleid where inserted.itemid = itemsforsale.itemid) where itemsforsale.itemid in (select inserted.itemid from inserted) Thực hiện cập nhật cho bảng SALE: update sale set salequantity = salequantity + 10 where itemid = 1 Ví dụ 4: Ví dụ này minh họa INSTEAD OF trigger. Trigger dưới đây sẽ không cho thực hiện thao tác xóa trên bảng CUSTOMERS. create trigger t_RollbackDelete on customers after delete as 81
- rollback tran 5.3.5 Kích hoạt trigger dựa trên sự thay đổi dữ liệu trên cột Thay vì chỉ định một trigger được kích hoạt trên một bảng, ta có thể chỉ định trigger được kích hoạt và thực hiện những thao tác cụ thể khi việc thay đổi dữ liệu chỉ liên quan đến một số cột nhất định nào đó của cột. Trong trường hợp này, ta sử dụng mệnh đề IF UPDATE trong trigger. IF UPDATE không sử dụng được đối với câu lệnh DELETE. Trở lại ví dụ 3 trong phần định nghĩa trigger: if exists (select name from sysobjects where name = 't_DecreaseSumQuantityOfItemForSale') drop trigger t_DecreaseSumQuantityOfItemForSale go create trigger t_DecreaseSumQuantityOfItemForSale on SALE for update as if update(salequantity) update ITEMSFORSALE set itemsforsale.quantity = itemsforsale.quantity - (select sum(inserted.salequantity - deleted.salequantity) from deleted inner join inserted on deleted.saleid = inserted.saleid where inserted.itemid = itemsforsale.itemid) where itemsforsale.itemid in (select inserted.itemid from inserted) Trong ví dụ này trigger sẽ được kích hoạt khi có sự thay đổi dữ liệu trong cột salequantity của bảng Sale. Nếu có sự thay đổi dữ liệu trên các cột khác thì trigger sẽ không được kích hoạt. Câu lệnh dưới đây không làm cho trigger kích hoạt. update sale set itemid = 3 where itemid = 2 Mệnh đề IF UPDATE có thể xuất hiện nhiều lần trong phần thân của trigger. Khi đó, mệnh đề IF UPDATE nào đúng thì phần câu lệnh của mệnh đề đó sẽ được thực thi khi trigger được kích hoạt. 82
- 5.3.6 Sử dụng trigger và Giao tác (TRANSACTION) Khi một trigger được kích hoạt, SQL Server luôn tạo ra một giao tác theo dõi những thay đổi do câu lệnh kích hoạt trigger hoặc do bản thân trigger gây ra. Sự theo dõi này cho phép CSDL quay trở lại trạng thái trước đó. Ví dụ: Ví dụ dưới đây xây dựng trigger không cho phép nhập vào một bản ghi trong bảng SALE khi số lượng hàng bán lớn hơn số lượng hàng thực tế còn lại trong bảng ITEMSFORSALE if exists (select name from sysobjects where name = 't_CheckQuantity' and type = 'TR') drop trigger t_CheckQuantity go create trigger t_CheckQuantity on sale for insert as declare @insertedQuantity decimal(18,2) declare @currentQuantity decimal(18,2) declare @itemid int select @itemid = itemid from inserted select @insertedQuantity = salequantity from inserted select @currentQuantity = quantity from itemsforsale where itemid = @itemid if(@currentquantity < @insertedquantity) print N'số lượng nhập vào lớn hơn số lượng hiện có' rollback tran Tiến hành thêm vào bảng SALE số liệu như sau: insert into sale values(2, 1000) 83
- 5.4 DDL TRIGGER Được giới thiệu trong SQL Server 2005, khác với DML trigger được kích hoạt khi có sự thay đổi dữ liệu trên bảng, DDL trigger được thiết kế để đáp ứng lại các sự kiện diễn ra trên server hay trên CSDL. Một DDL trigger có thể được kích hoạt khi người dùng thực hiện các lệnh CREATE TABLE hay DROP TABLE. Ở cấp độ server, DDL trigger có thể được kích hoạt khi có một tài khoản mới được tạo ra DDL trigger được lưu trữ trong CSDL mà DDL trigger được gắn vào. Với các Server DDL Trigger theo dõi các thay đổi ở cấp độ Server, được lưu trữ trong CSDL master. DDL trigger được tạo ra cũng bằng câu lệnh CREATE TRIGGER với cấu trúc như sau: CREATE TRIGGER tên_trigger ON { ALL SERVER | DATABASE } FOR { loại_sự_kiện } [ , n ] AS { các_câu_lệnh_SQL} Trong đó: ALL SERVER | DATABASE: quy định trigger sẽ kích hoạt dựa trên các sự kiện diễn ra trên Server hay các sự kiện diễn ra trên CSDL. loại_sự_kiện: là một sự kiện đơn ở cấp độ Server hay cấp độ CSDL làm kích hoạt DDL trigger như: CREATE_TABLE, ALTER_TABLE, DROP_TABLE Ví dụ 1: Câu lệnh dưới đây xây dựng một trigger được kích hoạt khi xảy ra các sự kiện ở cấp độ CSDL. Trigger này sẽ ngăn chặn các lệnh DROP TABLE và ALTER TABLE. create trigger t_safety on database for CREATE_TABLE, DROP_TABLE as print N'Phải xóa trigger t_safety trước khi ALTER hay DROP bảng' rollback tran Tiến hành xóa bảng ORDERDETAIL drop table orderdetail 84
- Ví dụ 2: Câu lệnh dưới đây xây dựng một trigger được kích hoạt khi xảy ra các sự kiện ở cấp độ Server. Trigger này sẽ ngăn chặn việc tạo ra một account login mới IF EXISTS (SELECT * FROM sys.server_triggers WHERE name = 't_DoNotAllowCreateNewLogin') DROP TRIGGER t_DoNotAllowCreateNewLogin ON ALL SERVER GO CREATE TRIGGER t_DoNotAllowCreateNewLogin ON ALL SERVER FOR CREATE_LOGIN AS PRINT N'Phải DROP trigger t_DoNotAllowCreateNewLogin trước khi tạo account' rollback GO Tiến hành tạo một account login mới: create login test with password = '123456' 5.5 Enable/ Disable TRIGGER Trigger cần bị vô hiệu hóa trong một số trường hợp: Trigger gây ra lỗi trong quá trình xử lý CSDL Quá trình nhập hay khôi phục những dữ liệu không thỏa trigger. Vô hiệu hóa trigger bằng lệnh DISABLE TRIGGER có cấu trúc như sau: DISABLE TRIGGER tên_trigger ON { tên_đối_tượng | DATABASE | SERVER } Ví dụ 1: Ví dụ này sẽ vô hiệu hóa trigger t_DoNotAllowCreateNewLogin disable trigger t_DoNotAllowCreateNewLogin on all server Tiến hành tạo một account login mới: create login newLogin with password = '12345' 85
- Ví dụ 2: Ví dụ này sẽ khôi phục lại trigger t_ DoNotAllowCreateNewLogin enable trigger t_DoNotAllowCreateNewLogin on all server Tiến hành tạo một account login mới: create login newLogin1 with password = '12345' 86
- 6 Sao lưu và phục hồi dữ liệu (Backup and Restore) Chương này sẽ giới thiệu kỹ thuật sao lưu (backup) và khôi phục (restore) dữ liệu, là kỹ thuật thường được sử dụng bảo đảm an toàn dữ liệu phòng trường hợp CSDL có sự cố. 6.1 Các lý do phải thực hiện Backup Trong quá trình thực hiện quản trị CSDL SQL Server thì một số nguyên nhân sau đây bắt buộc bạn phải xem xét đến kỹ thuật sao lưu và khôi phục dữ liệu: Thiết bị lưu trữ (CSDL nằm trên các thiết bị lưu trữ này) bị hư hỏng. Người dùng vô tình xóa dữ liệu. Các hành động vô tình hay cố ý phá hoại CSDL. 6.2 Các loại Backup Microsoft SQL Server 2005 cung cấp hai kỹ thuật sao lưu CSDL chính: full backup và differential backup. 6.2.1 Full backup và Differential backup Full backup: sao lưu một bản đầy đủ của CSDL trên các phương tiện lưu trữ. Quá trình full backup có thể tiến hành mà không cần offline CSDL, nhưng quá trình này lại chiếm một lượng lớn tài nguyên hệ thống và có thể ảnh hưởng nghiêm trọng tới thời gian đáp ứng các yêu cầu của hệ thống. Differential backup: được xây dựng nhằm làm giảm thời gian cần thiết để thực hiện quá trình full backup. Differential backup chỉ sao lưu những thay đổi trên dữ liệu kể từ lần full backup gần nhất. Trong những hệ thống CSDL lớn, quá trình differential backup sẽ sử dụng tài nguyên ít hơn rất nhiều so với quá trình full backup và có thể không ảnh hưởng đến hiệu suất của hệ thống. Quá trình differential chỉ sao lưu những sự thay đổi của dữ liệu từ lần full backup gần nhất, do đó khi có sự cố với CSDL nếu không có bản sao lưu của quá trình full backup thì bản sao lưu của quá trình differential backup sẽ trở nên vô nghĩa. Ví dụ: Công ty XYZ thực hiện full backup vào cuối ngày thứ 6 hàng tuần và thực hiện differential backup vào tối các ngày từ thứ 2 tới thứ 5. Nếu CSDL có sự cố vào sáng thứ 4, quản trị viên CSDL sẽ phục hồi dữ liệu bằng bản sao lưu của quá trình full backup của ngày thứ 6 tuần trước và sau đó phục hồi các thay đổi của dữ liệu bằng cách áp dụng bản sao lưu của quá trình differential backup vào ngày thứ 3. 87
- 6.2.2 Transaction log backup Quá trình full backup và differential backup chiếm nhiều tài nguyên hệ thống và ảnh hưởng đến hiệu suất làm việc hệ thống nên thường được thực hiện vào sau giờ làm việc. Tuy nhiên điều này có thể dẫn đến các mất mát dữ liệu trong một ngày làm việc nếu CSDL có sự cố trước khi quá trình sao lưu diễn ra. Transaction log backup là một giải pháp nhằm giảm thiểu tối đa lượng dữ liệu có thể mất khi có sự cố CSDL. Trong quá trình hoạt động, SQL Server sử dụng transaction log để theo dõi tất cả các thay đổi trên CSDL. Log bảo đảm CSDL có thể phục hồi sau những sự cố đột xuất và cũng đảm bảo người dùng có thể quay ngược các kết quả trong các giao tác CSDL. Các giao tác chưa hoàn thành được lưu trong log trước khi được lưu vĩnh viễn trong CSDL. Transaction log backup sao lưu transaction log của CSDL vào thiết bị lưu trữ. Mỗi khi transaction log được sao lưu, SQL Server bỏ đi các transaction đã thực hiện thành công (committed tracsaction) và ghi các transaction vào phương tiện sao lưu. Transaction log backup sử dụng tài nguyên hệ thống ít hơn rất nhiều so với full backup và differential backup, do đó có thể sử dụng transaction log backup bất kỳ thời gian nào mà không sợ ảnh hưởng đến hiệu suất hệ thống. Trở lại với ví dụ về công ty XYZ. Công ty này thực hiện full backup vào tối thứ 6 và differential backup vào tối từ thứ 2 tới thứ 5. Công ty thực hiện thêm quá trình transaction log backup mỗi giờ một lần. Giả sử sự cố CSDL xảy ra vào 9h:05 sáng thứ 4. Quá trình khôi phục lại CSDL nhu sau: Dùng full backup và differential backup của tối thứ 6 và tối thứ 3 để phục hồi lại trạng thái CSDL vào tối thứ 3. Tuy nhiên quá trình này vẫn còn để mất dữ liệu trong 2 giờ (7 – 9h) sáng thứ 4. Tiếp theo sử dụng 2 bản sao lưu transaction backup lúc 8h và 9h sáng để khôi phục CSDL về trạng thái lúc 9h sáng thứ 4. 88
- 6.3 Các thao tác thực hiện quá trình Backup và Restore trong SQL Server 2005 Express Edition 6.3.1 Sao lưu (Backup) Click OK 89
- Click OK. Quá trình sao lưu hoàn tất 6.3.2 Phục hồi (Restore) 91
- Click OK hai lần 92
- Click OK. Quá trình phục hồi hoàn tất 93
- 7 Các hàm quan trọng trong T-SQL Ngôn ngữ T-SQL có nhiều hàm có thể tham gia vào câu lệnh T-SQL. Những hàm này thực hiện các nhiệm vụ quan trọng khác nhau. Trong chương này sẽ trình bày một số các hàm thông dụng để làm việc với các kiểu dữ liệu số, chuỗi, ngày/thời gian và giá trị NULL trong SQL Server 2005. 7.1 Các hàm làm việc với kiểu dữ liệu số Các hàm quan trọng làm việc với kiểu dữ liệu số là hàm ISNUMERIC và ham ROUND 7.1.1 Hàm ISNUMERIC Hàm isNumeric kiểm tra một giá trị có phải thuộc kiểu dữ liệu số hay không. Ví dụ: Câu lệnh dưới đây trả về tên khách hàng, và một cột có tên NUMERIC. Cột này sẽ mang giá trị 0 nếu địa chỉ khách hàng không phải là số và ngược lại select CUSTOMERNAME, isnumeric(ADDRESS) as ISNUMERIC from customers 7.1.2 Hàm ROUND Hàm ROUND trả về một giá trị số, đã được làm tròn theo một độ đài chỉ định Cấu trúc hàm ROUND như sau: ROUND ( số_làm_tròn , độ_dài_làm_tròn ) Khi sử dụng hàm ROUND cần lưu ý: số_làm_tròn phải có kiểu dữ liệu số (numeric data type) như int, float, decimal trừ kiểu dữ liệu dạng nhị phân. Cho dù số_làm_tròn thuộc kiểu dữ liệu gì, kết quả hàm ROUND luôn trả về kiều số nguyên. Nếu độ_dài_làm_tròn là số âm và lớn hơn số chữ số phía trước dấu thập phân thì hàm ROUND trả về 0. Ví dụ 1: 94
- select ROUND(123.9994, 3), ROUND(123.9995, 3) Ví dụ 2: select ROUND(123.4545, 2),ROUND(123.45, -2) Ví dụ 3: SELECT ROUND(150.75, 0), ROUND(150.75, 0, 1) 7.2 Các hàm làm việc với kiểu dữ liệu chuỗi Các hàm quan trọng bao gồm LEFT, RIGHT, LEN, REPLACE, STUFF, SUBSTRING, LOWER, UPPER, LTRIM, and RTRIM. 7.2.1 Hàm LEFT Hàm LEFT trả về một chuỗi ký tự có chiều dài được chỉ định tính từ bên trái của chuỗi. Ví dụ: select left('Nha Trang', 5) 7.2.2 Hàm RIGHT Hàm RIGHT tương tự hàm LEFT nhưng tính từ bên phải của chuỗi Ví dụ: select right('Nha Trang', 5) 7.2.3 Hàm SUBSTRING Hàm STRING trích xuất một chuỗi con từ một chuỗi cho trước. Cấu trúc hàm SUBSTRING như sau: SUBSTRING (chuỗi_ban_đầu, vị_trí_bắt_đầu, chiều_dài_chuỗi_con) Ví dụ 1: select substring ('Nha Trang', 2, 5) 95
- Ví dụ 2: Select substring(‘Nha Trang’, -2, 5) 7.2.4 Hàm LEN Hàm LEN trả về chiều dài một chuỗi Ví dụ: Select len(‘Nha Trang’) 7.2.5 Hàm REPLACE Hàm REPLACE thay thế một chuỗi bởi một chuỗi khác Ví dụ 1: Câu lệnh dưới đây thay thế chữ “Nha” trong chuỗi Nha Trang bằng chữ “nha” Select replace(‘Nha Trang’, ‘Nha’, ‘nha) Ví dụ 2: select replace(ADDRESS, 'Minh', 'Ninh') from customers 7.2.6 Hàm STUFF Hàm STUFF thay thế một số lượng xác định các ký tự trong một chuỗi bằng một chuỗi khác bắt đầu từ một vị trí được chỉ định. Ví dụ: 96
- select stuff('Nha Trang', 2, 3, ' ') 7.2.7 Hàm LOWER/UPPER Hàm LOWER chuyển các ký tự hoa trong chuỗi thành các kí tự thường. Hàm UPPER chuyển các chuỗi ký tự thường trong chuỗi thành các ký tự hoa. Ví dụ: select lower('Nha Trang'), upper('Nha Trang') 7.2.8 Hàm LTRIM/RTRIM Hàm LTRIM cắt các khoảng trắng bên trái của chuỗi, hàm RTRIM cắt khoảng trắng bên phải chuỗi. Ví dụ: declare @llen int declare @rlen int declare @len int select @llen = len(ltrim(' Nha Trang')), @rlen = len(rtrim('Nha Trang ')), @len = len('Nha Trang') select @llen, @rlen, @len 7.3 Các hàm làm việc với kiểu dữ liệu Ngày tháng/ Thời gian 7.3.1 Hàm GETDATE Hàm GETDATE trả về ngày giờ lúc thực hiện câu truy vấn. Ví dụ: select getdate() 7.3.2 Hàm DAY/ MONTH/ YEAR Hàm DAY trả về ngày của một một giá trị thuộc kiểu datetime. Hàm MONTH trả về tháng của một giá trị thuộc kiểu datetime 97
- Hàm YEAR trả về năm của một giá trị thuộc kiểu datetime. Ví dụ: select day(orderdate) as DAYOFORDER, month(orderdate) as MONTHOFORDER, year(orderdate) as YEAROFORDER from orders o inner join customers c on c.customerid = o.customerid where c.customerid = 3 7.3.3 Hàm DATEPART Trong quá trình làm việc với các CSDL, đôi lúc ta muốn biết xem một ngày nào đó thuộc quý mấy trong năm, hay thuộc tuần thứ mấy trong tháng. Hàm DATEPART giúp giải quyết các yêu cầu trên một cách dễ dàng. Cấu trúc hàm DATEPART như sau: DATEPART (yêu_cầu_trích_xuất, giá_trị_trích_xuất) giá_trị_trích_xuất là một giá trị thuộc kiểu datetime. yêu_cầu_trích_xuất: ngày, tháng, năm, quý, . Khi có một yêu cầu trích xuất nào đó, chúng ta sẽ có các chữ viết tắt tương ứng với các yêu cầu đó. Bảng dưới đây mô tả các yêu chữ viết tắt và các yêu cầu trích xuất tương ứng. Ý nghĩa Chữ viết tắt Năm yy, yyyy Quý qq,q Tháng mm,m Số ngày đã qua trong năm dy,y Ngày dd,d Tuần wk,ww Số ngày đã qua trong tuần dw Giờ hh Phút mi,n Giây ss,s Ví dụ: select datepart(yyyy, orderdate)as YEAROFORDERDATE, datepart(qq, orderdate)as QUARTEROFORDERDATE, 98
- datepart(m, orderdate) as MONTHOFORDERDATE, datepart(wk, orderdate) as WEEKOFORDERDATE, datepart(d, orderdate) as DATEOFORDERDATE, datepart(dy, Orderdate), datepart(dw, orderdate) from orders 7.3.4 Hàm DATENAME Tương tự hàm DATEPART nhưng hàm DATENAME trả về một chuỗi ký tự Ví dụ: select datename(yyyy, orderdate)as YEAROFORDERDATE, datename(qq, orderdate)as QUARTEROFORDERDATE, datename(m, orderdate) as MONTHOFORDERDATE, datename(wk, orderdate) as WEEKOFORDERDATE, datename(d, orderdate) as DATEOFORDERDATE, datename(dy, Orderdate), datename(dw, orderdate) from orders 7.4 Hàm CAST và CONVERTER Chuyển đổi một giá trị thuộc kiểu dữ liệu này sang một kiểu dữ liệu khác. Hàm CAST và CONVERTER cung cấp cùng một chức năng. Một điểm thuận lợi khi dùng CONVERTER là khi chuyển đổi, hàm này cũng cho phép người dùng sẽ định dạng lại giá tri kết quả theo ý muốn. Cấu trúc hàm CAST và CONVERTER như sau: CAST (biểu_thức/giá_ trị AS kiểu_dữ liệu [độ_dài_kiểu_dữ_liệu ]) CONVERT ( kiểu_dữ liệu [độ_dài_kiểu_dữ_liệu ] , biểu_thức/giá_ trị [ ,kiểu_định_dạng] ) Năm 2 chữ số Năm 4 chữ số Output 0 hoặc 100 mon dd yyyy hh:mi AM (PM) 1 101 mm/dd/yy 2 102 yy.mm.dd 99
- 3 103 dd/mm/yy 4 104 dd.mm.yy 5 105 dd-mm-yy 6 106 dd mon yy 7 107 Mon dd, yy 8 108 hh:mm:ss 9 hoặc 109 mon dd yyyy hh:mi:ss:mmmAM (PM) 10 110 mm-dd-yy 11 111 yy/mm/dd 12 112 yymmdd 13 hoặc 113 dd mon yyyy hh:mm:ss:mmm(24h) 14 114 hh:mi:ss:mmm(24h) Ví1 dụ: select CUSTOMERNAME, convert (varchar, BIRTHDAY, 103) as BIRTHDAY, ADDRESS from Customers where Customername = 'Le Thi Hoa' and year(getdate()) - year(BIRTHDAY) > 20 Hàm CONVERT và hàm CAST có thể sử dụng kết hợp với nhau để cho kết qua như mong muốn. Ví dụ: select c.CUSTOMERID, c.CUSTOMERNAME, convert(varchar(20),cast(SUM(i.UNITPRICE*od.QUANTITY) as money),1) as SUMTOTAL from customers c inner join orders o on o.customerid = c.customerid inner join orderdetail od on o.orderid = od.orderid inner join items i on i.itemid = od.itemid group by c.customerid, c.customername 100
- 8 Kết nối vào SQL Server 2005 từ các ngôn ngữ lập trình để xây dựng các ứng dụng liên quan đến CSDL Mục tiêu cuối cùng của việc học hệ quản trị CSDL Microsoft SQL Server 2005 là người học biết dùng hệ quản trị này trong việc xây dựng các CSDL cho các ứng dụng quản lý trong thực tế. Đồng thời sử dụng các công cụ trong Microsoft SQL Server 2005 để quản trị CSDL của mình. 8.1 Cấu hình Microsoft SQL Server 2005 Như đã nói trong chương 1, Microsoft SQL Server 2005 sử dụng hai kiểu định danh người dùng: Windows Authentication và SQL Server Authentication. Windows Authentication: thích hợp trong việc xây dựng các ứng dụng quản lý trên máy đơn ( nghĩa là SQL Server và ứng dụng quản lý cùng trên một máy). Những ứng dụng này thường có CSDL khá nhỏ và tốc độ tăng trưởng của CSDL không cao. SQL Server Authentication: thích hợp trong việc xây dựng các ứng dụng quản lý có CSDL lớn, nhiều người dùng cùng lúc. Trong các ứng dụng này, CSDL được đặt trên Database Server, ứng dụng trên các máy trạm sẽ thực hiện các kết nối vào Database Server này và thực hiện các thao tác trên CSDL. Các kết nối này được gọi là các kết nối từ xa (remote connection). Tuy nhiên, khi kết nối một máy tính đến một thể hiện (instance) của Microsoft SQL Server 2005 để tạo một kết nối từ xa, bạn có thể nhận một thông báo lỗi như sau: Microsoft SQL Native Client: An error has occurred while establishing a connection to the server. When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. Lỗi này xảy ra vì Microsoft SQL Server chưa được cấu hình để chấp nhận các kết nối từ xa. Mặc định, phiên bản SQL Server 2005 Express Edition và phiên bản SQL Server 2005 Developer Edition không cho phép các kết nối từ xa. Để cấu hình SQL Server 2005 chấp nhận các kết nối từ xa cần thực hiện các bước sau: Cho phép tiếp nhận các kết nối từ xa trên thể hiện của SQL Server mà các ứng dụng máy trạm cần kết nối. Kích hoạt dịch vụ SQL Server Browser Cấu hình tường lửa cho phép các dữ liệu liên quan đến SQL Server và dịch vụ SQL Server Browser được lưu thông trên mạng. 101
- 8.1.1 Cho phép tiếp nhận các kết nối từ xa trên thể hiện của SQL Server Click Start -> Programs -> Microsoft SQL Server 2005 -> Configuration Tools -> SQL Server Surface Area Configuration. Trong trang SQL Server 2005 Surface Area Configuration, click Surface Area Configuration for Services and Connections. Trong trang Surface Area Configuration for Services and Connections, mở nút Database Engine, click Remote Connections, click Local and remote connections, click chọn giao thức thích hợp (giao thức này được lựa chọn dưa trên giao thức thực tế được dùng trong môi trường làm viêc), sau đó click Apply. Trong môi trường học tập, chúng ta thường dùng giao thức TCP/IP. Lưu ý: Click OK khi nhận được thông báo: Changes to Connection Settings will not take effect until you restart the Database Engine service. Trong trang Surface Area Configuration for Services and Connections, mở nút Database Engine, click Service, click Stop, đợi đến khi dịch vụ MSSQLSERVER dừng lại, sau đó click Start để khởi động lại dịch vụ MSSQLSERVER . Lưu ý: nếu chúng ta không cần sử dụng SQL Server 2005 thường xuyên, ta có thể để chế độ khởi động của dịch vụ MSSQLSERVER là manual (nghĩa là khi nào cần dùng thì sẽ kích hoạt) nhằm giảm bớt thời gian khởi động Windows và tiết kiệm tài nguyên hệ thống 8.1.2 Kích hoạt dịch vụ SQL Server Browser Nếu chúng ta thao tác trên SQL Server 2005 bằng việc sử dụng tên thể hiện (instance name) và không chỉ định một port cụ thể trong chuỗi kết nối (chúng ta sẽ nói về chuỗi kết nối kỹ hơn trong phần kết nối các ngôn ngữ lập trình với SQL Server 2005) thì chúng ta phải kích hoạt dịch vụ SQL Server Browser để cho phép các kết nối từ xa. Ví dụ: SQL Server 2005 Express Edition được cài đặt với một thể hiện mặc định là tên_máy_tính\SQLEXPRESS. Chúng ta chỉ cần kích hoạt dịch vụ SQL Server Browser một lần bất kể chúng ta có bao nhiêu 102
- thể hiện của SQL Server 2005 đang được sử dụng (running). Để kích hoạt dịch vụ SQL Server Browser, cần làm theo các bước sau: Click Start -> Programs -> Microsoft SQL Server 2005 -> Configuration Tools, click SQL Server Surface Area Configuration. Trong trang SQL Server 2005 Surface Area Configuration, click Surface Area Configuration for Services and Connections. Trong trang Surface Area Configuration for Services and Connections, click SQL Server Browser, click Automatic for Startup type, click Apply. Lưu ý: tương tự như dịch vụ MSSQLSERVER, nếu chọn startup type là Automatic thì dịch vụ SQL Server Browser sẽ được khởi động khi Windows khởi động Kiểm tra tình trạng dịch vụ trong Service status. Sau đó click Start nếu dịch vụ này đang bị Stop. Lưu ý: Thực hiện các bước trên làm tăng các nguy cơ cho hệ thống vì hệ thống sẽ hiện thị thông tin của các thể hiện của SQL Server đạng chạy trên hệ thống. Các nguy cơ này có thể được giảm thiểu bằng cách không kích hoạt dịch vụ SQL Server Browser và kết nối vào thể hiện của SQL Server thông qua một port. Chi tiết có thể tham khảo Microsoft Book Online theo các chủ đề sau: SQL Server Browser Service Connecting to the SQL Server Database Engine Client Network Configuration 8.1.3 Tạo các ngoại lệ trên Windows Firewall Các bước dưới đây áp dụng cho Windows Firewall trong Windows XP Service Pack 2 (SP2) và trong Windows Server 2003. Nếu tường lửa được sử dụng trên máy tính cài đặt SQL Server 2005, các kết nối từ bên ngoài sẽ bị chặn trừ khi SQL Server 2005 và SQL Serve Browser có thể liên lạc qua tường lửa. Chúng ta phải tạo ra các ngoại lệ cho mỗi thể hiện của SQL Server 2005 (muốn thể hiện nào tiếp nhận kết nối từ xa thì chúng ta phải tạo ngoại lệ cho thể hiện đó) và một ngoại lệ cho dịch vụ SQL Server Browser. Việc tạo ngoại lệ theo các bước sau: Click Start -> Programs -> Microsoft SQL Server 2005 ->Configuration Tools -> SQL Server Configuration Manager. 103
- Trong trang SQL Server Configuration Manager, click SQL Server Services, right-click tên thể hiện, và click Properties. Trong trang SQL Server Browser Properties, click tab Advanced, xác định instanceID trong danh sách thuộc tính, và click OK. Lưu ý: Chúng ta có thể có nhiều thể hiện SQL Server, do đó chúng ta phải xác định đúng instanceID nào chúng tao muốn tạo ngoại lệ. Để mở Windows Firewall, click Start, click Run, đánh firewall.cpl, và click OK. Tạo ngoại lệ cho SQL Server 2005 trong Windows Firewall Trong Windows Firewall, click tab Exceptions, sau đó click Add Program. Trong cửa sổ Add a Program window, click Browse. C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Binn\sqlservr.exe, click Open, và click OK. Lưu ý: Đường dẫn có thể khác nhau tùy thuộc vào thư mục cài đặt của SQL Server 2005. MSSQL.1 là nơi lưu trữ cho instanceID chúng ta thu được trong bước trên. Lặp lại các bước trên cho mỗi thể hiện của SQL Server 2005 cần thiết lập ngoại lệ. Tạo ngoại lệ cho dịch vụ SQL Server Browser trong Windows Firewall Trong Windows Firewall, click tab Exceptions, và click Add Program. Trong cửa sổ Add a Program, click Browse. C:\Program Files\Microsoft SQL Server\90\Shared\sqlbrowser.exe, click Open, và click OK. Lưu ý: Đường dẫn có thể thay đổi tùy thuộc vào thư mục cài đặt của SQL Server 2005. 8.2 Kết nối vào SQL Server trong các ngôn ngữ lập trình 8.2.1 C# và VB.NET Tùy thuộc vào việc sử dụng .NET Data Provider (tập các đối tượng phục vụ việc trao đổi dữ liệu) nào trong .NET Framework và việc sử dụng hình thức Authentication nào để truy xuất dữ liệu trong SQL Server 2005, chúng ta sẽ có các cách khác nhau để kết nối đến SQL Server 2005. Trong phần trình bày này sẽ sử dụng System.Data.SqlClient là một Data Provider phổ biến để kết nối với SQL Server 2005. Trong C#: public void ConnectToSql () 104
- { System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection (); // TODO Xây dựng chuỗi kết nối conn.ConnectionString = "integrated security=true;data source=tên_SQLSERVER;" + "persist security info=False;initial catalog=tên_CSDL"; try { conn.Open(); // Xây dựng code để tương tác với CSDL ở đây } catch (Exception ex) { MessageBox.Show("Failed to connect to data source"); } finally { conn.Close(); } } Trong VB.NET Public Sub ConnectToSql() Dim conn As New SqlClient.SqlConnection ' TODO Xây dựng chuỗi kết nối conn.ConnectionString = & _ "integrated security=true;data source=tên_SQL Server;" & _ "persist security info=False;initial catalog=tên_CSDL" Try conn.Open() ' Xây dựng code để tương tác với CSDL ở đây Catch ex As Exception 105
- MessageBox.Show("Failed to connect to data source") Finally conn.Close() End Try End Sub Trong hai ví dụ trên chúng ta xây dựng hàm kết nối vào SQL Server 2005 mà thành phần quan trọng nhất là chuỗi kết nối vào CSDL: Trong C#: "integrated security=true;data source=tên_SQLSERVER;" + "persist security info=False;initial catalog=tên_CSDL"; Trong VB.NET: "integrated security=true;data source=tên_SQL Server;" & _ "persist security info=False;initial catalog=tên_CSDL" Trong đó: Intergrated security = true: sử dụng Windows Authentication data source: chỉ định tên thể hiện của SQL Server 2005 mà chúng ta muốn kết nối. persist security info: Thiết lập mặc định cho từ khóa persist security info là false. Thiết lập sang giá trị true sẽ cho phép các dữ liệu nhạy cảm bao gồm UserID và password có thể được truy xuất khi kết nối được mở initial catalog: Tên CSDL mà chúng ta muốn tương tác. Ví dụ chuỗi kết nối sử dụng Windows Authentication: "integrated security=true;data source=.\\SQLExpress" + "persist security info=False;initial catalog=myDB"; Ví dụ chuỗi kết nối sử dung SQL Server Authentication: "persist security info=False;User ID = ; password = “ + “initial catalog=myDB; data source=.\\SQLExpress "; 8.2.2 VB 6 Ví dụ dưới đây minh họa việc xây dựng ứng dụng CSDL bằng VB6. Giả sử chúng ta có CSDL tên là Test, SQL Server là .\\SQLExpress, User là sa, Password là 1234. Private Sub Command1_Click() Dim connectionString As String Dim commandString As String Dim sqlConnection As ADODB.Connection 106
- Dim rs As Recordset connectionString="PROVIDER=SQLOLEDB; DATA SOURCE=.\SQLEXPRESS;” connectionString = “UID=sa; PWD=1234;DATABASE=Test" commandString = "select count(*) as count from Users where UserName = '" commandString = commandString & Text1.Text & "' and Password = '" commandString = commandString & Text2.Text & "'" Set sqlConnection = New ADODB.Connection sqlConnection.Open (connectionString) Set rs = New Recordset rs.Open commandString, sqlConnection If (rs("count") = 1) Then MsgBox "Login successfully" End If End Sub 107
- Tài liệu tham khảo 1. Giáo trình hệ quản trị cơ sở dữ liệu SQL Server, Khoa CNTT, Đại học Huế. 2. SQL Server 2005, T-SQL Recipes: Problem, Solution, Approach – Appress Publisher. 3. Sams Teach yourself Microsoft SQL Server 2005 Express in 24 hours. 108