Cập nhật gần đây Toggle Comment Threads | Phím tắt

  • Hình đại diện của Không hiểu

    Viet nguyen van 6:20 pm on May 22, 2019 Liên kết tĩnh | Trả lời  

    Sử dụng trigger trong SQL qua ví dụ cơ bản. 

    Trigger là gì ?

    ?

    Hiểu đơn giản thì Trigger là một stored procedure không có tham số. Trigger thực thi một cách tự động khi một trong ba câu lệnh Insert, Update, Delete làm thay đổi dữ liệu trên bảng có chứa trigger. 

    Cú pháp của Trigger

    CREATE TRIGGER tên_trigger ON tên_bảng
    FOR {DELETE, INSERT, UPDATE}
    AS 
      câu_lệnh_sql
    
    

    Trigger dùng làm gì ?

    • Trigger thường được sử dụng để kiểm tra ràng buộc (check constraints) trên nhiều quan hệ (nhiều bảng/table) hoặc trên nhiều dòng (nhiều record) của bảng.
    • Ngoài ra việc sử dụng Trigger để chương trình có những hàm chạy ngầm nhằm phục vụ nhưng trường hợp hữu hạn và thường không sử dụng cho mục đích kinh doanh hoặc giao dịch. Đọc thêm tại đây

    Bài toán đặt ra.

    • Bạn có 2 bảng kho hàng và đặt hàng liên kết với nhau bởi mã hàng.
    • Khi người dùng đặt hàng hãy tự động cập nhật số lượng tồn trong bảng kho hàng.

    Giải pháp

    • Khi người dùng đặt hàng ta chỉ có 3 loại thao tác chính với CSDL là : Insert, Delete, Update
    • Vậy chỉ cần tạo 3 trigger tương ứng là ok 
    • Người dùng đặt hàngSố lượng còn trong kho = Số lượng còn – Số lượt đặt
    • Người dùng hủy không đặt hàng nữa: Số lượng còn trong kho = Số lượng còn + Số lượt đặt
    • Người dùng cập nhật Số lượng đặt => Số lượng còn tăng giảm tùy ý

    Vấn đề

    • Ở 2 trường hợp insert và delete ta thực hiện bình thường. Nhưng trong trường hợp update Số lượng hàng tồn sẽ sảy ra trong 3 trường hợp sau.
    1. Số lượng đặt ban đầu = 5 sau đó tăng lên 10 => số lượng trong kho sẽ giảm 10 tương ứng
    2. Số lượng đặt lúc này = 10 sau đó giảm xuống 3 => số lượng trong kho sẽ tăng 7 tương ứng
    • Tận dụng việc trong sql câu lệnh update = Insert new row To Delete old row cõ nghĩa là khi thực hiện update CSDL trong sql sẽ chạy việc insert dữ liệu mới trước sau đó sẽ xóa đi bảng cũ.

    Giải quyết vấn đề

    • Tận dụng việc sử dụng Trigger luôn tồn tại 2 bảng inserted và deleted ta sẽ rút ra 1 công thức cập nhật trung trong mọi trường hợp
    SLTonKhoCu = SLTonKhoCu - inserted.SLDatHang + deleted.SLDatHang
    
    

    Thực hiện qua ví dụ nhỏ

    1. Ban đầu thêm dữ liệu và select nó ra 
    1. Đặt hàng 5 sản phẩm với mã là 1

     

    1. Cập nhật lên 10
    1. Cập nhật về 3
    1. Cập nhật một số thông tin khác mà không liên quan đến số lượng
    1. Xóa đơn đặt hàng

    Source code bài toàn 

    1. Trigger thêm
    1. Trigger Xóa
    1. Trigger Sửa

    /* cập nhật hàng trong kho sau khi đặt hàng hoặc cập nhật */
    CREATE TRIGGER trg_DatHang ON tbl_DatHang AFTER INSERT AS 
    BEGIN
    	UPDATE tbl_KhoHang
    	SET SoLuongTon = SoLuongTon - (
    		SELECT SoLuongDat
    		FROM inserted
    		WHERE MaHang = tbl_KhoHang.MaHang
    	)
    	FROM tbl_KhoHang
    	JOIN inserted ON tbl_KhoHang.MaHang = inserted.MaHang
    END
    GO
    /* cập nhật hàng trong kho sau khi cập nhật đặt hàng */
    CREATE TRIGGER trg_CapNhatDatHang on tbl_DatHang after update AS
    BEGIN
       UPDATE tbl_KhoHang SET SoLuongTon = SoLuongTon -
    	   (SELECT SoLuongDat FROM inserted WHERE MaHang = tbl_KhoHang.MaHang) +
    	   (SELECT SoLuongDat FROM deleted WHERE MaHang = tbl_KhoHang.MaHang)
       FROM tbl_KhoHang 
       JOIN deleted ON tbl_KhoHang.MaHang = deleted.MaHang
    end
    GO
    /* cập nhật hàng trong kho sau khi hủy đặt hàng */
    create TRIGGER trg_HuyDatHang ON tbl_DatHang FOR DELETE AS 
    BEGIN
    	UPDATE tbl_KhoHang
    	SET SoLuongTon = SoLuongTon + (SELECT SoLuongDat FROM deleted WHERE MaHang = tbl_KhoHang.MaHang)
    	FROM tbl_KhoHang 
    	JOIN deleted ON tbl_KhoHang.MaHang = deleted.MaHang
    END
    
    

    Kết luận

    ?

    Việc mà bạn sử dụng Trigger là không bắt buộc và chúng ta thường tưởng rằng vì thế mà chả ai dùng nó là hoàn toàn sai . Nhưng Trigger theo như mình tìm hiểu qua thì vẫn có rất nhiều nơi sẽ sử dụng nó vào mục đích riêng của họ.

     
  • Hình đại diện của Không hiểu

    Viet nguyen van 5:20 pm on May 23, 2019 Liên kết tĩnh | Trả lời  

    Sử dụng trigger trong SQL qua ví dụ cơ bản. 

    TechBlog

    PHẠM ANH TUẤN https://VIBLO.ASIA/P/SU-DUNG-TRIGGER-TRONG-SQL-QUA-VI-DU-CO-BAN-AWJ538…

    Trigger là gì ?

    Hiểu đơn giản thì Trigger là một stored procedure không có tham số. Trigger thực thi một cách tự động khi một trong ba câu lệnh Insert, Update, Delete làm thay đổi dữ liệu trên bảng có chứa trigger. 

    Cú pháp của Trigger

    CREATE TRIGGER tên_trigger ON tên_bảng
    FOR {DELETE, INSERT, UPDATE}
    AS 
      câu_lệnh_sql
    

    Trigger dùng làm gì ?

    • Trigger thường được sử dụng để kiểm tra ràng buộc (check constraints) trên nhiều quan hệ (nhiều bảng/table) hoặc trên nhiều dòng (nhiều record) của bảng.
    • Ngoài ra việc sử dụng Trigger để chương trình có những hàm chạy ngầm nhằm phục vụ nhưng trường hợp hữu hạn và thường không sử dụng cho mục đích kinh doanh hoặc giao dịch. Đọc thêm tại đây

    Bài toán đặt ra.

    • Bạn có 2 bảng kho hàng và đặt hàng liên kết với nhau bởi mã hàng.
    • Khi người dùng đặt hàng hãy tự động cập nhật số lượng tồn trong bảng kho hàng.

    Giải pháp

    • Khi người dùng đặt hàng ta chỉ có 3 loại thao tác chính với CSDL là : Insert, Delete, Update
    • Vậy chỉ cần tạo 3 trigger tương ứng là ok 
    • Người dùng đặt hàngSố lượng còn trong kho = Số lượng còn – Số lượt đặt
    • Người dùng hủy không đặt hàng nữa: Số lượng còn trong kho = Số lượng còn + Số lượt đặt
    • Người dùng cập nhật Số lượng đặt => Số lượng còn tăng giảm tùy ý

    Vấn đề

    • Ở 2 trường hợp insert và delete ta thực hiện bình thường. Nhưng trong trường hợp update Số lượng hàng tồn sẽ sảy ra trong 3 trường hợp sau.
    1. Số lượng đặt ban đầu = 5 sau đó tăng lên 10 => số lượng trong kho sẽ giảm 10 tương ứng
    2. Số lượng đặt lúc này = 10 sau đó giảm xuống 3 => số lượng trong kho sẽ tăng 7 tương ứng
    • Tận dụng việc trong sql câu lệnh update = Insert new row To Delete old row cõ nghĩa là khi thực hiện update CSDL trong sql sẽ chạy việc insert dữ liệu mới trước sau đó sẽ xóa đi bảng cũ.

    Giải quyết vấn đề

    • Tận dụng việc sử dụng Trigger luôn tồn tại 2 bảng inserted và deleted ta sẽ rút ra 1 công thức cập nhật trung trong mọi trường hợp
    SLTonKhoCu = SLTonKhoCu - inserted.SLDatHang + deleted.SLDatHang
    
    

    Thực hiện qua ví dụ nhỏ

    1. Ban đầu thêm dữ liệu và select nó ra 
    1. Đặt hàng 5 sản phẩm với mã là 1

     

    1. Cập nhật lên 10
    1. Cập nhật về 3
    1. Cập nhật một số thông tin khác mà không liên quan đến số lượng
    1. Xóa đơn đặt hàng

    Source code bài toàn 

    1. Trigger thêm
    1. Trigger Xóa
    1. Trigger Sửa

    /* cập nhật hàng trong kho sau khi đặt hàng hoặc cập nhật */
    CREATE TRIGGER trg_DatHang ON tbl_DatHang AFTER INSERT AS 
    BEGIN
    	UPDATE tbl_KhoHang
    	SET SoLuongTon = SoLuongTon - (
    		SELECT SoLuongDat
    		FROM inserted
    		WHERE MaHang = tbl_KhoHang.MaHang
    	)
    	FROM tbl_KhoHang
    	JOIN inserted ON tbl_KhoHang.MaHang = inserted.MaHang
    END
    GO
    /* cập nhật hàng trong kho sau khi cập nhật đặt hàng */
    CREATE TRIGGER trg_CapNhatDatHang on tbl_DatHang after update AS
    BEGIN
       UPDATE tbl_KhoHang SET SoLuongTon = SoLuongTon -
    	   (SELECT SoLuongDat FROM inserted WHERE MaHang = tbl_KhoHang.MaHang) +
    	   (SELECT SoLuongDat FROM deleted WHERE MaHang = tbl_KhoHang.MaHang)
       FROM tbl_KhoHang 
       JOIN deleted ON tbl_KhoHang.MaHang = deleted.MaHang
    end
    GO
    /* cập nhật hàng trong kho sau khi hủy đặt hàng */
    create TRIGGER trg_HuyDatHang ON tbl_DatHang FOR DELETE AS 
    BEGIN
    	UPDATE tbl_KhoHang
    	SET SoLuongTon = SoLuongTon + (SELECT SoLuongDat FROM deleted WHERE MaHang = tbl_KhoHang.MaHang)
    	FROM tbl_KhoHang 
    	JOIN deleted ON tbl_KhoHang.MaHang = deleted.MaHang
    END
    
    

    Kết luận

    Việc mà bạn sử dụng Trigger là không bắt buộc và chúng ta thường tưởng rằng vì thế mà chả ai dùng nó là hoàn toàn sai . Nhưng Trigger theo như mình tìm hiểu qua thì vẫn có rất nhiều nơi sẽ sử dụng nó vào mục đích riêng của họ.

     
  • Hình đại diện của Không hiểu

    Viet nguyen van 3:39 pm on May 23, 2019 Liên kết tĩnh | Trả lời  

    Bài 5 – Lập trình với CSDL 

    Hiểu và trình bày được các phương thức, thuộc tính của các đối tượng truy xuất cơ sở dữ liệu, cách thức truy xuất, duyệt nội dung cơ sở dữ liệu; các đối tượng hiển thị nội dung các bản ghi trong cơ sở dữ liệu; các cú pháp lệnh truy xuất cơ sở dữ liệu


    Biến cục bộ

    Khai báo biến cục bộ

    DECLARE @Tên_biến Kiểu_dữ_liệu [, ...] 
    Ví dụ:
    DECLARE @Tongsldat INT, @Hotenncc CHAR(50)
    DECLARE @Ngayxh DATETIME
    

    Dùng để lưu trữ các giá trị tạm thời trong quá trình tính toán

    • Biến phải có kiểu dữ liệu
    • Biến muốn sử dụng trong một batch phải khai báo trước

    Gán giá trị cho biến Sử dụng lệnh SET hoặc SELECT

    SET @Biến = Giá_trị
    SET @a = 5
    Select @Biến = Tên_Cột From Tên_Bảng
    Select @ConLai = TonCuoiKy From TonKho Where MaVTu = 'VT010' And NamThang = '200402'
    

    Xem giá trӏ hiện hành của biến

    Khi có kết hợp với chuỗi, phải đổi kiểu dữ liệu sang kiểu chuỗi bằng hàm CAST hay CONVERT

    Print 'Giá trị của @A ' + cast(@A as char(4))
    

    Phạm vi hoạt động của biến: Một biến chỉ có phạm vi hoạt động cục bộ

    • Trong một Batch
    • Trong một Stored Procedure hay Trigger
    DECLARE @Ngaydhgn DATETIME
    SELECT @Ngaydhgn=MAX(NGAYDH)
    FROM DONDH
    GO
    
    PRINT 'Ngày đặt hàng gần nhất: ' + CONVERT(CHAR(12),@Ngaydhgn)
    GO 
    

    Biến hệ thống

    Ý nghĩa sử dụng

    • Cung cấp các thông tin hệ thống
      • Phiên bản SQL Server
      • Số dòng dữ liệu vừa được xử lý bởi câu lệnh
      • Mã lỗi
      • Số lượng kết nối
      • Tình trạng cursor
    • Không cần khai báo
      • Biến do SQL Server định sẵn
      • Tên bắt đầu bởi @@

    Một vài biến hệ thống thường dùng

    • @@RowCount
      • Tổng số mẩu tin được tác động của câu lệnh truy vấn gần nhất.
    • @@Error
      • Số mã lỗi của câu lệnh thực hiện gần nhất
      • Khi một câu lệnh thực hiện thành công thì giá trị là 0.
    • @@Fetch_Status
      • Trạng thái của việc đọc dữ liệu trong bảng theo cơ chế từng mẩu tin (cursor).
      • Khi đọc dữ liệu của mẩu tin thành công thì giá trị là 0.

    Các toán tử

    Toán tử số học

    Toán tử số hóa sql
    SELECT 'Hello' + ' ' + 'The World!'
    SELECT 'Ngày đặt hàng D007 là: ' + CAST(NGAYDH AS CHAR(11))
    FROM DONDH
    WHERE SODH='D007'
    

    Toán tử so sánh

    Toán tử so sánh sql
    SELECT * FROM VATTU
    WHERE
      (DVTINH='Bộ' AND PHANTRAM>10) 
      OR
      (DVTINH='Cái' AND PHANTRAM>20)
    

    Cấu trúc điều khiển

    Cấu trúc rẽ nhánh IF…ELSE

    IF Biểu_thức_luận_lý
       Câu_lệnh1 | Khối_lệnh1
    [ELSE
       Câu_lệnh2 | Khối_lệnh2 ] 
    
    IF (SELECT COUNT(*) FROM CTPXUAT WHERE SLXUAT>4) > 0
    BEGIN
        PRINT 'Danh sách các hàng hóa bán với số lượng > 4'
        SELECT CTPX.MAVTU, TENVTU, SLXUAT
           FROM CTPXUAT CTPX INNER JOIN VATTU VT
                ON VT.MAVTU=CTPX.MAVTU
           WHERE SLXUAT>4
    END
    ELSE
     PRINT 'Chưa bán hàng hóa nào với số lượng >4'
    

    Cú pháp If Exists

    IF EXISTS (Câu_lệnh_SELECT)
       Câu_lệnh1 | Khối_lệnh1
    [ELSE
       Câu_lệnh2 | Khối_lệnh2]
    
    IF EXISTS (SELECT * FROM CTPXUAT WHERE SLXUAT>4)
    BEGIN
        PRINT 'Danh sách các hàng hóa bán với số lượng > 4'
        SELECT CTPX.MAVTU, TENVTU, SLXUAT
           FROM CTPXUAT CTPX INNER JOIN VATTU VT ON VT.MAVTU=CTPX.MAVTU
           WHERE SLXUAT>4
    END
    ELSE
     PRINT 'Chưa bán hàng hóa nào với số lượng >4' 
    

    Cấu trúc lặp WHILE

    WHILE Biểu_thức_luận_lý
    BEGIN
       Các_lệnh_lặp
    END
    
    DECLARE @Songuyen INT
    SET @Songuyen=100
    WHILE (@Songuyen<110)
    BEGIN
       PRINT 'Số nguyên : ' + CONVERT(CHAR(3), @Songuyen)
       SET @Songuyen = @Songuyen + 1
    END
    

    Khái niệm về cursor

    • Các lệnh của SQL Server làm việc trên một nhóm nhiều mẩu tin
    • Cursor là cấu trúc giúp làm việc từng mẩu tin tҥi một thời điểm
      • Khai báo cursor như một câu lệnh SELECT
      • Có thể di chuyển giữa các mẩu tin trong cursor để làm việc
      • Có thể dùng cursor để cập nhật dữ liệu (Update, Delete)

    Các bước sử dụng kiểu dữ liệu cursor

    • Định nghĩa biến kiểu cursor bằng lệnh DECLARE
      • Có hai loại cursor: Local, Global
      • Cách di chuyển mẩu tin trong cursor: Forward only, scroll
      • Cách quản lý dữ liệu của cursor: static, dynamic, keyset
    • Sử dụng lệnh OPEN để mở ra cursor đã định nghĩa trước đó
    • Đọc và xử lý trên từng dòng dữ liệu bên trong cursor
      • Sử dụng biến @@Fetch_status  Các lệnh Fetch và cấu trúc while
    • Đóng cursor lại bằng lệnh CLOSE và DEALLOCATE
      • Sau khi close, có thể mở lại
      • Deallocate: hủy cursor khỏi bộ nhớ

    Cú pháp Declare

    DECLARE Tên_cursor CURSOR
    [LOCAL | GLOBAL]
    [FORWARD_ONLY | SCROLL]
    [STATIC | DYNAMIC | KEYSET]
    [READ_ONLY | SCROLL_LOCK]
    FOR Câu_lệnh_SELECT
    [FOR UPDATE [OF Danh_sách_cột_cập_nhật]]
    
    DECLARE cur_Vattu CURSOR
    DYNAMIC
    FOR
       SELECT * FROM VATTU 
    

    Cú pháp Open

    DECLARE cur_Vattu CURSOR
    DYNAMIC
    FOR
       SELECT * FROM VATTU
    OPEN cur_Vattu 
    

    Cú pháp FETCH

    • Absolute n: Đọc dòng thứ n trong cursor
    • Relative n: Đọc dòng thứ n kể từ vị trí hiện hành
    FETCH [NEXT | PRIOR | FIRST | LAST
       | ABSOLUTE n | RELATIVE n]
        FROM Tên_cursor
        [INTO Danh_sách_biến]
    
    

    Ví dụ hoàn chỉnh

    --1. Khai báo biến cursor
    DECLARE cur_Vattu CURSOR KEYSET
    FOR SELECT * FROM VATTU
        WHERE MAVTU LIKE 'TV%'
        ORDER BY MAVTU
    
    --2. Mở cursor
    OPEN cur_Vattu
    
    --3. Đọc dữ liệu
    FETCH NEXT FROM cur_Vattu
    WHILE @@FETCH_STATUS = 0
    BEGIN
     -- Xử lý dòng mới vừa đọc được
     -- Thực hiện đọc tiếp các dòng kế
     FETCH NEXT FROM cur_Vattu
    END
    
    --4. Đóng cursor
    CLOSE cur_Vattu
    DEALLOCATE cur_Vattu
    

    Các hàm chuyển đổi kiểu dữ liệu

    Một hàm của SQL Server có thể sử dụng ở bất cứ đâu thay cho một giá trị cụ thể

    • Đổi một số thành chuỗi
      • STR (Số_thực, Số_ký_tự [, Số_lẻ])
    • Đổi kiểu dữ liệu
      • CAST (Biểu_thức AS Kiểu_dữ_liệu)
    • Đổi kiểu dữ liệu và định dạng
      • CONVERT (Kiểu_dữ_liệu, Biểu_thức [, Định_dạng])

    Một số định dạng chuỗi ngày thông dụng

    Một số định dạng ngày thông dụng

    Các hàm ngày giờ

    • Cộng ngày
      • DATEADD (Đơn_vị, Con_số, Ngày_chỉ_định)
    • So sánh hai biến ngày
      • DATEDIFF (Đơn_vị, Ngày1, Ngày2)
    • Lấy tên ngày, tháng, năm
      • DATENAME (Đơn_vị, Ngày)
    • Thời điểm hiện hành
      • GETDATE()
    • Lấy một thành phần ngày, giờ trong biến ngày
      • DATEPART (Đơn_vị, Ngày)
    • Lấy ngày, tháng, năm của biến ngày
      • DAY (Ngày)
      • MONTH (Ngày)
      • YEAR (Ngày)
    Đơn vị ngày trong sql

    Các hàm toán học

    • Lấy trị tuyệt đối
      • ABS (Biểu_thức_số)
    • Hằng số Pi
      • PI()
    • Luỹ thừa
      • POWER (Biểu_thức_số, Số_mũ)
    • Lấy số ngẫu nhiên
      • RAND ([Số_nguồn])
    • Làm tròn số
      • ROUND (Biểu_thức_số, Vtrí_làm_tròn)
    • Dấu của kết quả biểu thức : SIGN (Biểu_thức_số)
    • Lấy căn bậc 2 : SQRT (Biểu_thức_số)

    Các hàm xử lý chuỗi

    • Hàm viết hoa, thường
      • UPPER (Chuỗi), LOWER (Chuỗi)
    • Hàm cắt chuỗi
      • LEFT (Chuỗi nguồn, Số_ktự), RIGHT (Chuỗi nguồn, Số_ktự)
      • SUBSTRING (Chuỗi nguồn,Vị_trí,Số_ktự)
    • Hàm cắt khoảng trắng, tҥo chuỗi khoảng trắng
      • LTRIM (Chuỗi), RTRIM (Chuỗi), SPACE (N)
    • Hàm tҥo chuỗi lặp
      • REPLICATE (Chuỗi_lặp, N)
    • Chiều dài chuỗi
      • LEN (Chuỗi)
    • Đảo chuỗi
      • REVERSE (Chuỗi)
    • Tìm và thay thế chuỗi
      • REPLACE (Chuỗi nguồn, Chuỗi_tìm, Chuỗi_thay_thế)
    • Đổi từ số thành ký tự và ngược lại
      • CHAR (Số) , ASCII(Ký_tự)

    Xử lý lỗi TRY…CATCH

    • Ý nghĩa : Thực hiện các lệnh trong khối TRY, nếu gặp lỗi sẽ chuyển qua xử lý bằng các lệnh trong khối CATCH
    • Cú pháp :
    BEGIN TRY
       { các câu lệnh }
    END TRY
    BEGIN CATCH
       { các câu lệnh}
    END CATCH 
    
    
    • Các điểm cần lưu ý:
      • TRY và CATCH phải cùng lô xử lý
      • Sau khối TRY phải là khối CATCH
      • Có thể lồng nhiều cấp
    • Ví dụ
    BEGIN TRY
       SELECT * FROM BangKhongTonTai;
    END TRY
    BEGIN CATCH
       SELECT
         ERROR_NUMBER() as ErrorNumber,
         ERROR_MESSAGE() as ErrorMessage;
    END CATCH 
    

    Một số hàm ERROR thường dùng

    • ERROR_NUMBER() : Trả về mã số của lỗi
    • ERROR_MESSAGE() Trả về chuỗi lỗi
    • ERROR_SEVERITY() returns the error severity.
    • ERROR_STATE() returns the error state number.
    • ERROR_LINE() : Trả về dòng gây ra lỗi
    • ERROR_PROCEDURE() Trả về tên thủ tục/ trigger gây ra lỗi

    Thủ tục RAISERROR

    • Ý nghĩa : Trả thông báo lỗi về cho ứng dụng
    • Cú pháp :
    Raiserror(tbao_loi, muc_do, trang_thai [, cac_tham_so] ) 
    

    Trong đó:

    • tbao_loi :
      • mã thông báo lỗi do người dùng định nghĩa trước bằng sp_addmessage và được lưu trong sys.messages. Giá trị phải lớn hơn 50000.
      • chuỗi thông báo lỗi bất kỳ.
    • muc_do:
      • Số có giá trị từ 0
      • 25 thể hiện mức độ nghiêm trọng của lỗi.
    • trang_thai: Số từ 1-127 để xác định vị trí lỗi khi sử dụng cùng một tbao_loi tại nhiều điểm khác nhau
    • cac_tham_so : Hỗ trợ cho các tbao_loi cần tham số

    Ví dụ sử dụng RAISERROR

    IF @nPhanTram NOT BETWEEN 0 AND 100
    BEGIN
      SET @sErrMsg = N'Tỉ lệ phầm trăm phải nằm trong đoạn [0,100]'
      RAISERROR(@sErrMsg, 16, 1)
      RETURN
    END 
    
    

    Sử dụng cấu trúc điều khiển

    Cho biết đơn giá xuất trung bình của hàng hóa “Đầu DVD Hitachi 1 đĩa” trong bảng CTPXUAT hiện giờ là bao nhiêu? Nếu lớn hơn 3,800,000 thì in ra “không nên thay đổi giá bán”, ngược lại in ra “đã đến lúc tăng giá bán”

    --Cách 1
    IF    (
            SELECT avg(c.dgxuat)
            FROM ctpxuat c INNER JOIN  vattu v ON v.mavtu = c.mavtu
            WHERE v.tenvtu=N'Đầu DVD Hitachi 1 đĩa'
            GROUP BY c.mavtu,v.tenvtu
        ) > =3800000
    BEGIN
        print 'không nên thay dổi giá bán'
    END
    ELSE
    BEGIN
        print 'đã đến lúc tăng giá bán'
    END
    
    --Cách 2
    SELECT c.mavtu,v.tenvtu,avg(c.dgxuat)AS 'DG trungbinh',(
                CASE
                    WHEN AVG(c.dgxuat)> =3800000
                        THEN 'không nên thay dổi giá bán'
                    ELSE
                        'đã đến lúc tăng giá bán'
                END
                ) AS 'Ghi Chu'
    FROM ctpxuat c INNER JOIN  vattu v ON v.mavtu = c.mavtu
    WHERE v.tenvtu=N'Đầu DVD Hitachi 1 đĩa'
    GROUP BY c.mavtu,v.tenvtu
    GO
    

    Sử dụng hàm DATENAME để tính xem có đơn đặt hàng nào đã được lập vào ngày chủ nhật không? Nếu có thì in ra danh sách các đơn đặt hàng đó, ngược lại thì in ra chuỗi “Ngày lập các đơn đặt hàng đều là hợp lệ”

    --Cach 1
    DECLARE @SoNgay  INT
    
    SELECT @SoNgay=COUNT(d.ngaydh)
    FROM dondh d
    WHERE DATENAME(dw,d.ngaydh)='sunday'
    
    IF @SoNgay>0
    BEGIN
        SELECT d.sodh, d.ngaydh, d.manhacc
        FROM dondh d
        WHERE DATENAME(dw,d.ngaydh)='sunday'
    END
    ELSE
        PRINT 'Ngày lập các đơn đặt hàng đều hợp lệ'
    GO
    
    --Cach 2
    IF EXISTS (SELECT * FROM dondh d WHERE DATENAME(dw,d.ngaydh)='sunday')
        SELECT * FROM dondh d WHERE DATENAME(dw,d.ngaydh)='sunday'
    ELSE
        PRINT N'Các hóa đơn đặt hàng có ngày hợp lệ'
    GO
    

    Hãy cho biết đã có bao nhiêu phiếu nhập hàng cho đơn đặt hàng D001, nếu có thì in ra “Có xx số phiếu nhập hàng cho đơn đặt hàng D001”, ngược lại thì in ra “Chưa có nhập hàng nào cho D001”

    DECLARE @SoPhieuDH INT
    DECLARE @TenDH VARCHAR(4)
    
    SET @TenDH='D001'
    
    SET @SoPhieuDH=(
        SELECT COUNT(p.sopn)
        FROM pnhap p
        WHERE p.sodh=@TenDH
    )
    
    IF @SoPhieuDH>0
        PRINT N'Có '+CAST(@SoPhieuDH AS VARCHAR(3))+ N' số phiếu nhập hàng cho dơn đặt hàng D001'
    ELSE
        PRINT 'Chưa có đơn dặt hàng nào cho D001'
    GO
    

    Hãy cho biết đơn đặt hàng D001 đã có nhập đủ hàng chưa, nếu có thì in ra “Đã nhập đủ hàng cho đơn đặt hàng D001”, ngược lại thì in ra “

    Chưa nhập đủ hàng cho đơn đặt hàng D001” Hãy cho biết vật tư TL90 đã có đặt hàng trong tháng 2/2009 chưa, nếu có thì in ra “Đã có đặt hàng với tổng số lượng đặt là xxx”, ngược lại thì in ra “Chưa có đặt hàng”

    DECLARE @TongDonDH INT
    DECLARE @MaVattu VARCHAR(4)
    DECLARE @Thang INT
    DECLARE @Nam INT
    SET @MaVattu='TL90'
    SET @Thang=2
    SET @Nam=2009
    
    IF EXISTS(
                        SELECT *
                        FROM ctdondh c INNER JOIN dondh d ON d.sodh = c.sodh
                        WHERE c.mavtu=@MaVattu AND MONTH (d.ngaydh)=@Thang AND YEAR(d.ngaydh)=@Nam
    )
    BEGIN
        SET @TongDonDH=(
                        SELECT SUM(c.sldat)
                        FROM ctdondh c INNER JOIN dondh d ON d.sodh = c.sodh
                        WHERE c.mavtu=@MaVattu AND MONTH (d.ngaydh)=@Thang AND YEAR(d.ngaydh)=@Nam
                        )
        PRINT N'Đã có đặt hàng với tổng số lựong dặt là '+CAST(@TongDonDH AS CHAR(3))
    END
    ELSE
        PRINT N'Chưa có đặt hàng'
    GO
    

    Liệt kê danh sách các đơn đặt hàng trong bảng DONDH có bổ sung thêm cột hiển thị thứ trong tuần (bằng tiếng Việt) của ngày đặt hàng

    SELECT dh.*, 'Thứ' =
                (
                    CASE DATENAME(dw,dh.ngaydh)
                        WHEN 'MONDAY'
                            THEN N'Thứ Hai'
                        WHEN 'TUESDAY'
                            THEN N'Thứ Ba'
                        WHEN 'WEDNESDAY'
                            THEN N'Thứ Tư'
                        WHEN 'THURSDAY'
                            THEN N'Thứ Năm'
                        WHEN 'FRIDAY'
                            THEN N'Thứ Sáu'
                        WHEN 'SATURDAY'
                            THEN N'Thứ Bảy'
                        ELSE
                            N'Chủ Nhật'
                    END
                )
    FROM dondh AS dh
    

    Tính tổng các số nguyên từ 1 đến 100

    DECLARE @Songuyen INT
    DECLARE @Tong INT
    SET @Tong = 0
    SET @Songuyen = 0
    while (@Songuyen <= 100)
    BEGIN
        SET @Tong = @Tong + @Songuyen
        SET @Songuyen = @Songuyen +1
    END
    print @Tong
    

    Tính tổng chẵn và tổng lẻ của các số nguyên từ 1 đến 100

    DECLARE @Songuyen INT
    DECLARE @TongChan INT
    DECLARE @TongLe INT
    SET @TongChan = 0
    SET @TongLe = 0
    SET @Songuyen = 0
    while (@Songuyen <= 100)
    BEGIN
        IF(@Songuyen % 2 = 0)
            BEGIN
                SET @TongChan = @TongChan + @Songuyen
            END
        ELSE
            BEGIN
                SET @TongLe = @TongLe + @Songuyen
            END
        SET @Songuyen = @Songuyen +1
    END
    print @TongChan
    print @TongLe
    

    Duyệt cursor và xử lý Hiển thị danh sách các thông tin trong bảng DONDH có thêm cột tổng số phiếu nhập

    DECLARE DonDH_cur CURSOR
    FOR
        SELECT dd.sodh, dd.ngaydh, dd.manhacc,COUNT(p.sodh)AS 'tongphieunhap'
        FROM DonDH dd LEFT JOIN PNhap p ON p.sodh=dd.sodh
        GROUP BY dd.sodh,dd.ngaydh,dd.manhacc
    
    DECLARE @sodh NCHAR(4), @ngaydh datetime, @manhacc NCHAR(3), @slnhap INT
    
    OPEN DonDH_cur
    FETCH NEXT FROM DonDH_cur INTO @sodh,@ngaydh,@manhacc,@slnhap
    WHILE 0=0
    BEGIN
      
        IF @@FETCH_STATUS<>0
            BREAK
        ELSE
        BEGIN
            PRINT @sodh+'  '+CAST(@ngaydh AS CHAR(6))+'  '+@manhacc+'  '+CAST(@slnhap AS CHAR)
        END
        FETCH NEXT FROM DonDH_cur INTO @sodh,@ngaydh,@manhacc,@slnhap
    END
    
    CLOSE DonDH_cur
    
    DEALLOCATE DonDH_cur
    
    GO
    


     
  • Hình đại diện của Không hiểu

    Viet nguyen van 3:38 pm on May 23, 2019 Liên kết tĩnh | Trả lời  

    Bài 4.5 – Tích hợp kết quả từ nhiều câu truy vấn SQL 

    Tích hợp kết quả từ nhiều câu truy vấn SQL (STRUCTURED QUERY LANGUAGE)

    Truy vấn dữ liệu trong sql thao tác này được sử dụng rất nhiều trong các hệ thống phần mềm hoặc website


    Tích hợp kết quả từ nhiều câu truy vấn

    Cú pháp mệnh đề UNION

    SELECT danh_sach_cot_1
    FROM Ten_bang_1
    UNION
    SELECT danh_sach_cot_2
    FROM ten_bang_2
    [ORDER BY ds_cot_sap_xep]
    

    Ví dụ

    SELECT mavtu,‘N’ as LOAI, sum(slnhap) as TONGSL
    FROM CTNVT
    GROUP BY mavtu
    UNION
    SELECT mavtu,‘X’ as LOAI, sum(slxuat) as TONGSL
    FROM CTXVT
    GROUP BY mavtu
    

    Mệnh đề EXCEPT

    Trả về những dòng có trong kết quả bên trái và không có trong kết quả bên phải

    Mệnh đề Except

    VD : Tìm những mặt hàng chưa xuất bao giờ

    SELECT mavt FROM vattu
    EXCEPT
    SELECT mavt FROM ctpx
    

    Mệnh đề INTERSECT

    Trả về những dòng có trong kết quả của cả 2 bên

    Mệnh đề INTERSECT

    VD : Tìm những mặt hàng vừa có nhập, vừa có xuất

    Select mavt from ctpn
    INTERSECT
    Select mavt from ctpx
    

    GROUP BY Toán tử ROLLUP

    • ROLLUP, CUBE là phần mở rộng của mệnh đề GROUP BY
    • Sử dụng để phát sinh các tổng trung gian từ các cột trong group by
    SELECT [cot,] ham_phan_nhom(cot). . .
    FROM ten_bang
    [WHERE dieu_kien]
    [GROUP BY bieu_thuc_phan_nhom [WITH ROLLUP]]
    [HAVING bieu_thuc_loc_nhom];
    [ORDER BY cot]
    

    Ví dụ toán tử ROLLUP

    SELECT maphong, macongviec, SUM(mucluong) as Luong
    FROM qlns.nhanvien
    WHERE maphong < 60
    GROUP BY maphong, macongviec WITH ROLLUP
    
    Ví dụ toán tử ROLLUP

    Ví dụ toán tử CUBE

    SELECT maphong, macongviec, SUM(mucluong)
    FROM qlns.nhanvien
    WHERE maphong < 60
    GROUP BY maphong, macongviec WITH CUBE
    
    ví dụ sử dụng toán tử Cube

    Hàm GROUPING

    • Hàm GROUPING có thể sử dụng với CUBE hoặc ROLLUP.
    • Sử dụng hàm GROUPING để tìm những dòng tổng được thêm bổ sung do các toán tử CUBE hoặc ROLLUP.
    • Hàm GROUPING trả về giá tri 0 hoặc 1.
    SELECT [cot,] ham_phan_nhom(cot) . ,
    GROUPING(bieu_thuc)
    FROM ten_bang
    [WHERE dieu_kien]
    [GROUP BY bieu_thuc_phan_nhom [WITH ROLLUP|CUBE]]
    [HAVING bieu_thuc_loc_nhom]
    [ORDER BY cot]
    

    Ví dụ hàm GROUPING

    SELECT maphong maph, macongviec macv,
    SUM(mucluong),
    GROUPING(maphong) nhom_maph,
    GROUPING(macongviec) nhom_macv
    FROM qlns.nhanvien
    WHERE maphong < 50
    GROUP BY maphong, macongviec WITH ROLLUP
    
    Ví dụ hàm GROUPING

    Chép dữ liệu ra bảng khác

    • Sử dụng mệnh đề SELECT INTO
      • Chép dữ liệu ra bảng mới
      • Chỉ chạy được 1 lần, ở lần sau bảng đã tồn tại thì sẽ gây ra lỗi
    • Cú pháp
    SELECT ds_cac_cot INTO ten_bang_moi
    FROM ten_bang
    

    Tổng hợp dữ liệu cuối nhóm

    • Mệnh đề COMPUTE, COMPUTE … BY
      • Sử dụng chung với các hàm thống kê SUM, COUNT, MAX, MIN, AVG
      • Với Compute By, phải có mệnh đề ORDER BY đi kèm
    • Cú pháp
    SELECT ds_cac_cot
    FROM ten_bang
    [ORDER BY Ten_cot_phan_nhom]
    COMPUTE COUNT|MIN|MAX|SUM|AVG (Ten_cot)
    [BY Ten_cot_phan_nhom]
    

    Sử dụng mệnh đề COMPUTE BY và các hàm tính toán để thống kê theo nhóm dữ liệu

    • Hiển thị các thông tin trong bảng CTPXUAT và bổ sung thêm cột thành tiền, sao cho có dòng thống kê tổng thành tiền ở từng nhóm phiếu xuất
    • Hiển thị trong bảng CTPNHAP các thông tin: mã vật tư, sốnhập hàng, số lượng nhập, đơn giá nhập và có dòng thống kê tổng số lượng, giá thấp nhất, giá cao nhất ở từng vật tư

    Giải bài tập :

    --Câu 1
     
    SELECT cx.sopx,cx.mavtu,cx.slxuat,cx.dgxuat
    FROM ctpxuat AS cx
    ORDER BY cx.sopx
    compute  SUM(cx.dgxuat) BY cx.sopx
     
    -- Câu 2
     
    SELECT cn.mavtu,cn.slnhap,cn.sopn,cn.dgnhap
    FROM ctpnhap AS cn
    ORDER BY cn.mavtu
    compute SUM(cn.slnhap),MIN(cn.dgnhap), MAX(cn.dgnhap) BY cn.mavtu
    
     
  • Hình đại diện của Không hiểu

    Viet nguyen van 3:37 pm on May 23, 2019 Liên kết tĩnh | Trả lời  

    Bài 4.4 – Truy vấn con SQL 

    Truy vấn con SQL (STRUCTURED QUERY LANGUAGE)

    Để kết hợp các bảng dữ liệu với nhau, ngoài các phép nối và các toán tử tập hợp, SQL cung cấp một cách khác để trả lại dữ liệu từ nhiều bảng gọi là truy vấn con (subquery)


    Vấn đề cần giải quyết

    Vấn đề cần giải quyết

    Cú pháp truy vấn con

    • Truy vấn con thi hành môt lần trước truy vấn chính (truy vấn cha).
    • Kết quả trả về từ truy vấn con được sử dụng trong câu truy vấn chính.
    SELECT ds_cot
    FROM bang
    WHERE bieu_thuc toan_tu(SELECT bieu_thuc FROM bang)
    

    Sử dụng truy vấn con

    SELECT honv, tennv
    FROM qlns.nhanvien
    WHERE mucluong >(SELECT mucluong FROM qlns.nhanvien WHERE tennv = ‘Huyền')
    
    Sử dụng truy vấn con

    Một số quy tắc khi sử dụng truy vấn con

    • Câu truy vấn con phải nằm trong cặp ngoặc đơn.
    • Đặt truy vấn con bên phải điều kiện so sánh.
    • Mệnh đề ORDER BY trong truy vấn con là không cần thiết ngoại trừ khi có sử dụng mệnh đề TOP.
    • Sử dụng các toán tử một dòng với các truy vấn con trả về một dòng và sử dụng các toán tử nhiều dòng với các truy vấn con trả về nhiều dòng.

    Các dạng truy vấn con

    • Truy vấn con một dòng
    • Truy vấn con nhiều dòng

    Truy vấn con một dòng

    • Trả về duy nhất 1 dòng
    • Sử dụng các toán tử so sánh một dòng
      • = Bằng
      • > Lớn hơn
      • >= Lớn hơn hoặc bằng
      • < Nhỏ hơn
      • <= Nhỏ hơn học bằng
      • <> Không bằng
    Truy vấn con một dòng

    Sử dụng hàm nhóm dữ liệu trong truy vấn con

    Sử dụng hàm nhóm dữ liệu trong truy vấn con

    Mệnh đề HAVING với truy vấn con

    • Các truy vấn con được thi hành trước tiên.
    • Kết quả được trả về cho mệnh đề HAVING trong truy vấn chính.
    Các truy vấn con được thi hành trước tiên. • Kết quả được trả về cho mệnh đề HAVING trong truy vấn chính.

    Câu lệnh sau sai ở chỗ nào?

    Câu lệnh sau sai ở chỗ nào?

    Câu lệnh sau có trả về kết quả nào không?

    Câu lệnh sau có trả về kết quả nào không?

    Truy vấn con nhiều dòng

    • Trả về nhiều dòng
    • Sử dụng các toán tử so sánh nhiều dòng
      • IN Bằng một trong các giá trị
      • ANY Chỉ cần thỏa một trong các giá trị trả về bởi truy vấn con
      • ALL Phải thỏa tất cả các giá trị trả về bởi truy vấn con

    Sử dụng toán tử ANY

    Sử dụng toán tử ANY

    Sử dụng toán tử ALL

    Sử dụng toán tử ALL

    Cẩn thận với giá trị NULL trong truy vấn con

    Tìm những nhân viên không quản lý bất cứ người nào

    ELECT nv.tennv
    FROM qlns.nhanvien nv
    WHERE nv.manhanvien NOT IN (SELECT qly.manguoiquanly FROM lns.nhanvien qly)
    

    Phần mở rộng của Truy vấn con

    • Truy vấn con nhiều cột
    • Truy vấn con trong mệnh đề FROM
    • Sử dụng truy vấn con đơn trị (scalar subquery)
    • Viết truy vấn con kết hợp (Correlated subquery)
    • Sử dụng hàm EXISTS

    Truy vấn con trả về nhiều cột

    Liệt kê danh sách những nhân viên được quản lý bởi bởi cùng một người và làm trong cùng phòng với nhân viên có mã số là 143.

    SELECT manhanvien, manguoiquanly, maphong
    FROM qlns.nhanvien
    WHERE (STR(manguoiquanly)+STR(maphong)) IN
         (SELECT STR(manguoiquanly)+STR(maphong)
          FROM qlns.nhanvien
          WHERE manhanvien = 143)
    AND manhanvien NOT IN (143)
    

    Sử dụng truy vấn con trong mệnh đề FROM

    SELECT a.tennv, a.mucluong,a.maphong, b.tb_luong
    FROM qlns.nhanvien a, 
    		(SELECT maphong,AVG(mucluong) tb_luong FROM qlns.nhanvien GROUP BY maphong) b
    WHERE a.maphong = b.maphong AND a.mucluong > b.tb_luong;
    

    Sử dụng truy vấn con trong mệnh đề FROM

    • Biểu thức truy vấn con đơn trị (A scalar subquery expression) là một truy vấn con trả về duy nhất một cột và một dòng.
    • Truy vấn con đơn trị có thể sử dụng:
      • Trong các điều kiện và biểu thức của CASE
      • Trong tất cả các mệnh đề của SELECT ngoại trừ GROUP BY

    Ví dụ Truy vấn con đơn trị

    Ví dụ Truy vấn con đơn trị

    Truy vấn con kết hợp

    Truy vấn con kết hợp (Correlated subqueries) được sử dụng cho việc xử lý từng dòng. Mỗi truy vấn con sẽ được thi hành một lần ứng với mỗi dòng của truy vấn cha

    Truy vấn con kết hợp
    Sử dụng truy vấn con kết hợp

    Sử dụng hàm EXISTS

    • Hàm EXISTS kiểm tra tồn tại kết quả trả về từ câu truy vấn con.
    • Tìm thấy một dòng trong truy vấn con:
      • Kết thúc tìm kiếm trong truy vấn con
      • Trả về kết quả TRUE
    • Nếu chưa tìm thấy dòng nào:
      • Trả về FALSE
      • Tiếp tục tìm kiếm trong truy vấn con
    Sử dụng hàm EXISTS

    Sử dụng câu truy vấn con (sub query)

    1. Hiển thị danh sách các nhà cung cấp mà chưa có đơn đặt hàng
    2. Hiển thị các đơn đặt hàng mà chưa có phiếu nhập
    3. Hiển thị danh sách các đơn đặt hàng có tổng số lần nhập là lớn nhất

    Giải bài tập :

    --Câu 1
    SELECT cc.*
    FROM nhacc AS cc
    WHERE
        cc.manhacc NOT IN ( SELECT dh.manhacc FROM dondh AS dh )
     
    --Câu 2
    SELECT dh.*
    FROM dondh AS dh
    WHERE dh.sodh NOT IN (SELECT pn.sodh FROM pnhap AS pn)
     
    --Câu 3
    SELECT  top 1 tmp.TongSLNhap AS 'TongSLNhap'
    FROM dondh AS dh
        LEFT JOIN
        (
            SELECT SUM(cn.slnhap) AS 'TongSLNhap',pn.sodh
            FROM ctpnhap cn
                LEFT JOIN pnhap pn ON cn.sopn = pn.sopn
            GROUP BY pn.sodh
        ) AS tmp ON tmp.sodh = dh.sodh
    ORDER BY TongSLNhap DESC
    

    Sử dụng câu truy vấn kết hợp (correlative query)

    1. Hiển thị danh sách các nhà cung cấp mà chưa có đơn đặt hàng
    2. Hiển thị danh sách các nhà cung cấp gồm các cột: mã nhà cung cấp, tên nhà cung cấp và tổng số đơn đặt hàng
    3. Hiển thị danh sách các nhà cung cấp gồm các cột: mã nhà cung cấp, tên nhà cung cấp, tổng số đơn đặt hàng và tổng số phiếu nhập

    Giải bài tập :

    -- Câu 1
    SELECT cc.*
    FROM nhacc AS cc
    WHERE
        cc.manhacc NOT IN
                (    SELECT dh.manhacc
                    FROM dondh AS dh
                    WHERE dh.manhacc = cc.manhacc
                )
     
    -- Câu 2
    SELECT
        cc.manhacc,
        cc.tennhacc,
        (    SELECT COUNT(*)
            FROM dondh AS dh
            WHERE dh.manhacc = cc.manhacc
        ) AS 'TongDondh'
    FROM nhacc AS cc
     
    --Hiển thịdanh sách các nhà cung cấp gồm các cột:
    --mã nhà cung cấp, tên nhà cung cấp,
    --tổng số đơn đặt hàng và tổng số phiếu nhập
     
    -- Câu 3
    SELECT
        cc.manhacc,
        cc.tennhacc,
        (    SELECT COUNT(*)
            FROM dondh AS dh
            WHERE dh.manhacc = cc.manhacc
        ) AS 'TongDondh',
        (
            SELECT COUNT(*)
            FROM pnhap AS pn
                INNER JOIN dondh AS dh ON pn.sodh = dh.sodh
            WHERE dh.manhacc = cc.manhacc
        ) AS 'TongPnhap'
    FROM nhacc AS cc
    
     
  • Hình đại diện của Không hiểu

    Viet nguyen van 3:36 pm on May 23, 2019 Liên kết tĩnh | Trả lời  

    Bài 4.3 – Gom nhóm dữ liệu SQL 

    Gom nhóm dữ liệu SQL (STRUCTURED QUERY LANGUAGE)

    Tìm hiểu và cách gom nhóm dữ liệu: Avg, Sum, Max, Min, Count, Distinct, Group By, Having


    Gom nhóm dữ liệu

    Các hàm nhóm dữ liệu là phép toán trên một tập các dòng để trả về một kết quả tương ứng mỗi nhóm

    Gom nhóm dữ liệu

    Các hàm nhóm dữ liệu

    • AVG ([DISTINCT|ALL] bieu_thuc)
    • COUNT ({*|[DISTINCT|ALL] bieu_thuc})
    • MAX ([DISTINCT|ALL] bieu_thuc)
    • MIN ([DISTINCT|ALL] bieu_thuc)
    • SUM ([DISTINCT|ALL] bieu_thuc)

    Cú pháp các hàm nhóm dữ liệu

    SELECT [cot,] ham_nhom_du_lieu(cot), ...
    FROM bang
    [WHERE dieu_kien]
    [GROUP BY cot]
    [ORDER BY cot]
    

    Sử dụng các hàm AVG,SUM & MAX,MIN

    • AVG và SUM : dùng cho dữ liệu kiểu số
    • MIN and MAX : Có thể dùng cho phần lớn các kiểu dữ liệu
    SELECT AVG(mucluong) as AVG_LLuong,
           MAX(mucluong) as MAX_Luong,
           MIN(mucluong) as MIN_Luong,
           SUM(mucluong) as SUM_Luong
    FROM qlns.nhanvien
    WHERE macongviec LIKE ‘%TT%'
    
    demo avg
    SELECT MIN(ngayvaolam), MAX(ngayvaolam)
    FROM qlns.nhanvien
    

    Sử dụng hàm COUNT

    • COUNT(*) Trả về số dòng có trong bảng.
    • COUNT(bieu_thuc) trả về số dòng khác null của bieu_thuc.
    SELECT COUNT(*)
    FROM qlns.nhanvien
    WHERE maphong = 50
    

    Sử dụng từ khóa DISTINCT

    • COUNT(DISTINCT bieu_thuc) Trả về số dòng khác nhau và khác NULL của bieu_thuc.
    • Ví dụ : Cho biết có bao nhiêu phòng ban khác nhau trong bảng NHANVIEN
    SELECT COUNT(DISTINCT maphong)
    FROM qlns.nhanvien;
    

    Tạo các phân nhóm dữ liệu

    Tạo các phân nhóm dữ liệu

    Mệnh đề GROUP BY

    SELECT cot, ham_nhom_du_lieu(cot)
    FROM bang
    [WHERE dieu_kien]
    [GROUP BY bieu_thuc_phan_nhom]
    [ORDER BY cot]
    

    Sử dụng mệnh đề GROUP BY

    • Tất cả các cột trong danh sách của SELECT nếu không phải là hàm nhóm dữ liệu thì phải tồn tại trong mệnh đề GROUP BY
    SELECT maphong, AVG(mucluong)
    FROM qlns.nhanvien
    GROUP BY maphong
    
    group by demo 1
    • Các cột trong GROUP BY không bắt buộc phải có trong danh sách của SELECT
    SELECT AVG(mucluong)
    FROM qlns.nhanvien
    GROUP BY maphong
    
    group by demo 2

    Tạo phân nhóm trên nhiều cột

    Tạo phân nhóm trên nhiều cột
    SELECT maphong maph, macongviec, SUM(mucluong)
    FROM qlns.nhanvien
    GROUP BY maphong, macongviec
    ORDER BY maphong, macongviec
    
    sử dụng gom nhóm nhiều dòng

    Lưu ý sử dụng các hàm nhóm dữ liệu

    • Bất kỳ một cột hay biểu thức trong danh sách của SELECT không phải là hàm nhóm dữ liệu thì phải có mệnh đề GROUP BY
    • Không thể sử dụng mệnh đề WHERE để giới hạn bớt các nhóm.
    • Sử dụng mệnh đề HAVING để lọc bớt các nhóm.
    • Không được phép sử dụng các hàm nhóm dữ liệu trong mệnh đề WHERE.

    Lọc bớt kết quả phân nhóm

    Lọc bớt kết quả phân nhóm

    Mệnh đề HAVING

    Để giới hạn bớt các nhóm trả về :

    1. Các dòng đã được phân nhóm.
    2. Các hàm nhóm dữ liệu đã đưa vào.
    3. Chỉ những nhóm thỏa điều kiện HAVING mới nằm trong tập kết quả trả về.
    SELECT cotcolumn, ham_nho_du_lieu
    FROM bang
    [WHERE dieu_kien]
    [GROUP BY bieu_thuc_nhom_du_lieu]
    [HAVING dieu_kien_loc_nhom_du_lieu]
    [ORDER BY cot]
    

    Sử dụng mệnh đề HAVING

    SELECT maphong, MAX(mucluong) as [Max Luong]
    FROM qlns.nhanvien
    GROUP BY maphong
    HAVING MAX(mucluong)>=10.000.000
    

    Bài tập

    1. Hiển thị danh sách các nhà cung cấp gồm các cột: mã nhà cung cấp, tên nhà cung cấp và tổng số đơn đặt hàng. Lọc ra các nhà cung cấp nào có tổng số đơn đặt hàng lớn hơn 1
    2. Hiển thị danh sách các thông tin trong bảng PNHAP có thêm cột tổng thành tiền, biết rằng Tổng thành tiền = Σ(sốlượng nhập x đơn giá nhập) của các mẩu tin chi tiết tương ứng trong bảng CTPNHAP
    3. Hiển thị danh sách các phiếu xuất hàng gồm các cột: sốphiếu xuất và tổng thành tiền. Trong đó sắp xếp theo thứ tự tổng thành tiền giảm dần
    4. Hiển thị danh sách các phiếu xuất hàng có tổng thành tiền lớn nhất
    --Câu 1
    SELECT cc.manhacc,cc.tennhacc,COUNT(dh.sodh) AS 'Tổng đơn đặt hàng'
    FROM nhacc AS cc
            LEFT JOIN dondh AS dh ON cc.manhacc = dh.manhacc
    GROUP BY cc.manhacc,cc.tennhacc
    HAVING COUNT(dh.sodh) > 1
     
    --Câu 2
    SELECT pn.sopn,pn.sodh,pn.ngaynhap,SUM(cn.dgnhap*cn.slnhap) AS 'Tổng tiền nhập'
    FROM pnhap AS pn
            LEFT JOIN ctpnhap AS cn ON pn.sopn = cn.sopn
    GROUP BY pn.sopn,pn.sodh,pn.ngaynhap
     
    --Câu 3
    SELECT cx.sopx,SUM(cx.dgxuat*cx.slxuat) AS 'Tổng tiền xuất'
    FROM pxuat AS px
            LEFT JOIN ctpxuat AS cx ON px.sopx = cx.sopx
    GROUP BY cx.sopx
    ORDER BY SUM(cx.dgxuat*cx.slxuat) DESC
     
    --Câu 4
    SELECT cx.sopx,MAX(cx.dgxuat*cx.slxuat) AS 'Tổng thành tiền lớn nhất'
    FROM pxuat AS px
            LEFT JOIN ctpxuat AS cx ON px.sopx = cx.sopx
    GROUP BY cx.sopx
    
     
  • Hình đại diện của Không hiểu

    Viet nguyen van 2:51 pm on May 23, 2019 Liên kết tĩnh | Trả lời  

    Bài 4.2 – Truy vấn dữ liệu từ nhiều bảng SQL 

    Truy vấn dữ liệu từ nhiều bảng SQL (STRUCTURED QUERY LANGUAGE)

    Tìm hiểu và cách sử dụng kết bảng: Kết bằng (EquiJoin), Kết không bằng (Non EquiJoin), Kết với chính mình (Self Join), Kết bằng mệnh đề Join


    Các loại phép kết

    • Kết bằng (EquiJoin)
    • Kết không bằng (Non EquiJoin)
    • Kết với chính mình (Self Join)
    • Kết bằng mệnh đề Join

    Phép kết bằng

    • Sử dụng điều kiện kết bằng trong mệnh đề WHERE
    • Nếu xuất hiện tên cột trùng nhau trong nhiều bảng thì bắt buộc phải sử dụng tên bảng hoặc bí danh bảng trước tên cột.
    SELECT bang1.cot, bang2.cot
    FROM bang1, bang2
    WHERE bang1.cot1 = bang2.cot2
    

    Phép kết bằng thực hiện như thế nào?

    phép bằng được thực hiện thế nào

    Kết quả nhận được từ phép kết bằng

    SELECT nhanvien.manhanvien, nhanvien.tennv,nhanvien.maphong,
           phong.maphong,phong.makhuvuc
    FROM qlns.nhanvien, qlns.phong
    WHERE nhanvien.maphong = phong.maphong;
    
    Phép bằng kết quả

    Sử dụng bí danh cho bảng

    Đơn giản hóa các câu truy vấn khi cần sử dụng tên bảng cho việc truy xuất các cột.

    SELECT nv.manhanvien, nv.tennv, nv.maphong,ph.maphong, ph.makhuvuc
    FROM qlns.nhanvien nv , qlns.phong ph
    WHERE nv.maphong = ph.maphong;
    

    Kết nhiều hơn hai bảng

    Để kết n bảng, ta cần tối thiểu n-1 phép kết. Ví dụ để kết ba bảng, ta cần tối thiểu hai phép kết bảng.

    Kết nhiều hơn hai bảng

    Kết không bằng

    kết không bằng

    Kết quả từ phép kết không bằng

    SELECT nv.tennv, nv.mucluong, lcv.maloaicv
    FROM qlns.nhanvien nv, qlns.loaicongviec lcv
    WHERE nv.mucluong BETWEEN lcv.mucluong_min AND lcv.mucluong_max;
    
    kết quả phép kết không bằng

    Kết với chính mình

    kết với chính mình
    SELECT nvien.honv+’ ‘+nvien.tennv + N' làm việc cho ' + nguoiqly.tennv as [Nhân viên và người QLý]
    FROM qlns.nhanvien nvien, qlns.nhanvien nguoiqly
    WHERE nvien.manguoiquanly = nguoiqly.manhanvien ;
    
    Kết cho chính mình kết quả

    Sử dụng mệnh đề JOIN để kết

    SELECT bang1.cot, bang2.cot
    FROM bang1
    [CROSS JOIN bang2] |
    [JOIN bang2
    ON(bang1.ten_cot = bang2.ten_cot)] |
    [LEFT|RIGHT|FULL [OUTER] JOIN bang2
    ON (bang1.ten_cot = bang2.ten_cot) ]
    

    Cross Joins

    Mệnh đề CROSS JOIN sẽ kết mỗi dòng của bảng 1 với tất cả các dòng của bảng 2

    cross joins

    Mệnh đề ON trong phép kết JOIN

    • Tách biệt đều kiện kết với các điều kiện chọn lọc dữ liệu khác.
    • Các câu truy vấn trở nên dễ đọc hơn.

    Sử dụng mệnh đề JOIN …ON…

    SELECT nv.manhanvien, nv.tennv, nv.maphong,ph.maphong, ph.makhuvuc
    FROM qlns.nhanvien nv JOIN qlns.phong ph 
         ON (nv.maphong = ph.maphong)
    
    cross joins demo

    Kết nhiều hơn hai bảng

    SELECT manhanvien, tenphong, tenkhuvuc, thanhpho
    FROM qlns.nhanvien nv
         JOIN qlns.phong ph
              ON ph.maphong = nv.maphong
         JOIN qlns.khuvuc kv
              ON ph.makhuvuc = kv.makhuvuc
    
    cross joins nhiều bảng

    Phép kết trái (LEFT [OUTER] JOIN)

    SELECT nv.honv, nv.tennv, nv.maphong, ph.tenphong
    FROM qlns.nhanvien nv
         LEFT OUTER JOIN qlns.phong ph
         ON (nv.maphong = ph.maphong)
    
    cross joins left

    Phép kết phải (RIGHT [OUTER] JOIN)

    SELECT nv.honv, nv.tennv, nv.maphong, ph.tenphong
    FROM qlns.nhanvien nv
         RIGHT OUTER JOIN qlns.phong ph
         ON (nv.maphong = ph.maphong)
    
    cross joins right

    Phép kết đầy đủ (FULL [OUTER] JOIN)

    SELECT nv.honv, nv.tennv, nv.maphong, ph.tenphong
    FROM qlns.nhanvien nv
         FULL OUTER JOIN qlns.phong ph
         ON (nv.maphong = ph.maphong)
    
    cross joins full

    Sử dụng biểu thức CASE trong truy vấn

    CASE Biểu_thức
    WHEN Giá_trị_1 THEN Biểu_thức_kết_quả_1
    WHEN Giá_trị_2 THEN Biểu_thức_kết_quả_2
    ...]
    [ELSE Biểu_thức_kết_quả_N]
    END
    
    • Giá trị 1, giá trị 2
      • Các giá trị cụ thể để so sánh bằng (=) với biểu thức
    • Biểu thức kết quả 1, biểu thức kết quả 2
      • Biểu thức sẽ được trả về khi việc so sánh của biểu thức bằng với các giá trị so sánh tương ứng

    Ví dụ

    SELECT LOAI=
    CASE LEFT(MAVTU, 2)
        WHEN 'DD' THEN 'Đầu DVD'
        WHEN 'VD' THEN 'Đầu VCD'
        WHEN 'TV' THEN 'Tivi'
        WHEN 'TL' THEN 'Tủ lạnh'
        WHEN 'BI' THEN 'Bia lon'
        WHEN 'LO' THEN 'Loa thùng'
        ELSE 'Chưa phân loại'
    END,
    MAVTU, TENVTU, DVTINH
    FROM VATTU
    ORDER BY LEFT(MAVTU, 2)
    

    Biểu thức CASE dạng tìm kiếm

    CASE
    WHEN Bt_logic_1 THEN Biểu_thức_kết_quả_1
    [WHEN Bt_logic_2 THEN Biểu_thức_kết_quả_2
    ...]
    [ ELSE Biểu_thức_kết_quả_N]
    END
    
    • Biểu thức logic1, biểu thức logic2
    • Các biểu thức luận lý dùng để thực hiện các phép so sánh trong biểu thức CASE.
    • Biểu thức kết quả 1, biểu thức kết quả 2
      • Biểu thức sẽ được trả về khi một trong các biểu thức luận lý so sánh có kết quả là đúng.

    Ví dụ

    SELECT GHICHU=
            CASE
               WHEN PHANTRAM <20 THEN 'Lời ít'
               WHEN PHANTRAM BETWEEN 20 AND 40 THEN 'Lời nhiều'
               ELSE 'Rất lời'
            END,
    TENVTU, DVTINH, PHANTRAM
    FROM VATTU
    ORDER BY PHANTRAM
    

    Bài tập

    1. Hiển thị danh sách các chi tiết phiếu xuất có thêm các cột tên vật tư, ngày xuất.Lọc theo số lượng xuất lớn hơn 5 và ngày xuất trong tháng 1/2009
    2. Hiển thị danh sách các nhà cung cấp gồm các thông tin sau: mã nhà cung cấp, tên nhà cung cấp đã có đặt hàng. Chú ý: không được trùng lắp dữ liệu
    3. Hiển thị danh sách các đơn đặt hàng gần đây nhất trong bảng DONDH
    4. Hiển thị danh sách các nhà cung cấp mà chưa có đơn đặt hàng
    -- Câu 1
    SELECT cx.*,vt.tenvtu,px.ngayxuat
    FROM ctpxuat AS cx
            INNER JOIN vattu AS vt ON cx.mavtu = vt.mavtu
            INNER JOIN pxuat AS px ON cx.sopx = px.sopx
    WHERE cx.slxuat > 5 AND MONTH(px.ngayxuat) = 1
     
    -- Câu 2
    SELECT DISTINCT cc.manhacc,cc.tennhacc
    FROM nhacc AS cc
        INNER JOIN dondh AS dh ON cc.manhacc = dh.manhacc
     
    -- Câu 3
    SELECT *
    FROM dondh AS dh
    ORDER BY dh.ngaydh DESC
     
    -- Câu 4
    SELECT *
    FROM nhacc AS cc
    WHERE cc.manhacc NOT IN (SELECT dh.manhacc FROM dondh AS dh)
    
     
  • Hình đại diện của Không hiểu

    Viet nguyen van 2:46 pm on May 23, 2019 Liên kết tĩnh | Trả lời  

    Bài 4.1 – Lệnh truy vấn dữ liệu SQL 

    Lệnh truy vấn dữ liệu SQL (STRUCTURED QUERY LANGUAGE)

    Tìm hiểu và học cách sử dụng: Select, Top, Alias, Distinct, Where


    Khả năng của lệnh SELECT

    • Chọn cột
    • Chọn dòng
    • Kết bảng
    khả năng của select

    Lệnh SELECT cơ bản

    • SELECT : xác định những cột gì
    • FROM : xác định bảng nào
    SELECT *|{[DISTINCT] cot|bieu_thuc [bi_danh],...}
    FROM bang
    

    Một số lưu ý khi viết câu lệnh SQL

    • Câu lệnh SQL không phân biệt chữ hoa, chữ thường.
    • Câu lệnh SQL có thể viết trên 1 hoặc nhiều dòng.
    • Các từ khóa không được viết tắt hoặc tách ra thành nhiều dòng.
    • Các mệnh đề khác nhau nên đặt trên những dòng khác nhau

    Các phép toán của biểu thức

    Tạo các biểu thức với các kiểu dữ liệu số và ngày bằng các phép toán số học

    • + Cộng
    •  Trừ
    • * Nhân
    • / Chia

    Sử dụng các phép toán số học

    SELECT tennv, mucluong, mucluong + 300
    FROM qlns.nhanvien
    
    sử dụng các phép toán học

    Khái niệm giá trị NULL

    • NULL là một giá trị chưa được xác định
    • NULL khác với zero hoặc giá trị rỗng
    • Các biểu thức số học có chứa giá trị NULL sẽ cho kết quả NULL
    SELECT tennv,mucluong,phucap,12*(mucluong+phucap)
    FROM qlns.nhanvien
    
    khái niệm giá trị null

    Khái niệm bí danh của cột (Alias)

    • Sự đổi tên tiêu đề cho cột
    • Rất hữu ích cho các biểu thức tính toán
    • Xuất hiện ngay sau tên cột hoặc biểu thức, có thể thêm từ khóa AS giữa tên cột và bí danh
    • Yêu cầu phải đặt trong dấu nháy kép hoặc móc vuông nếu có chứa khoảng trắng, ký tự đặc biệt hoặc sử dụng chữ hoa

    Sử dụng các bí danh cột

    SELECT tennv AS ten, phucap pc
    FROM qlns.nhanvien
    
    sử dụng alias
    SELECT tennv [Ten], mucluong*12 "Luong Mot Nam"
    FROM qlns.nhanvien
    
    sử dụng alias 2

    Loại bỏ những dòng trùng nhau

    SELECT maphong
    FROM qlns.nhanvien
    

    Theo mặc định thì kết quả hiểu thị của câu lệnh truy vấn là tất cả các dòng, bao gồm cả những dòng trùng nhau

    sử dụng DISTINCT
    SELECT DISTINCT maphong
    FROM qlns.nhanvien
    

    Loại bỏ những dòng trùng nhau

    sử dụng DISTINCT 2

    Chỉ thể hiện một số dòng Top

    SELECT [TOP (expression) [PERCENT][ WITH TIES ]]
    [danh_sach_cot]
    FROM ...
    

    Ví dụ : Cho biết tên và mức lương 3 nhân viên đầu tiên

    SELECT TOP 3 tennv, mucluong
    FROM qlns.nhanvien
    

    Giới hạn các dòng trả về Where

    Mệnh đề WHERE theo sau mệnh đề FROM.

    SELECT *|{[DISTINCT] cot|bieu_thuc [bi_danh],...}
    FROM bang
    [WHERE dieu_kien]
    

    Sử dụng mệnh đề WHERE

    SELECT manhanvien,honv,tennv,maphong,macongviec,ngayvaolam
    FROM qlns.nhanvien
    WHERE maphong = 20
    
    sử dụng where

    Bài tập

    1. Hiển thị danh sách các thông tin trong bảng CTPNHAP có thêm cột thành tiền biết rằng Thành tiền = SLNhap * DgNhap
    2. Hiển thị danh sách các nhà cung cấp trong bảng NHACC có cột địa chỉ ở quận 1 HCM, sắp xếp theo thứ tự họ tên tăng dần và số điện thoại giảm dần
    3. Hiển thị danh sách các phiếu xuất có ngày xuất nằm trong khoảng [1/1/2009, 31/1/2009]
    4. Hiển thị danh sách các chi tiết phiếu xuất có thêm các cột tên vật tư, ngày xuất. Lọc theo số lượng xuất lớn hơn 5 và ngày xuất trong tháng 1/2009
    5. Hiển thị danh sách các nhà cung cấp gồm các thông tin sau: mã nhà cung cấp, tên nhà cung cấp đã có đặt hàng. Chú ý: không được trùng lắp dữ liệu
    6. Hiển thị danh sách các đơn đặt hàng gần đây nhất trong bảng DONDH
    7. Hiển thị danh sách các nhà cung cấp mà chưa có đơn đặt hàng
    -- Chú ý : select * là lấy tất cả các cột trong bảng
     
    -- Câu 1
    SELECT *,(slnhap * dgnhap) AS 'Thành tiền'
    FROM ctpnhap
     
    -- Câu 2
    SELECT *
    FROM nhacc
    WHERE nhacc.diachi LIKE N'%Q1 HCM%'
    ORDER BY nhacc.tennhacc ASC,nhacc.dienthoai DESC
     
    -- Câu 3
    -- đinh dạng ngày là : MM/dd/yyyy
    SELECT *
    FROM pxuat
    WHERE pxuat.ngayxuat BETWEEN '1/1/2009' AND '1/31/2009'
     
    -- Câu 4
    SELECT cx.*,vt.tenvtu,px.ngayxuat
    FROM ctpxuat AS cx
            INNER JOIN vattu AS vt ON cx.mavtu = vt.mavtu
            INNER JOIN pxuat AS px ON cx.sopx = px.sopx
    WHERE cx.slxuat > 5 AND MONTH(px.ngayxuat) = 1
     
    -- Câu 5
    SELECT DISTINCT cc.manhacc,cc.tennhacc
    FROM nhacc AS cc
        INNER JOIN dondh AS dh ON cc.manhacc = dh.manhacc
     
    -- Câu 6
    SELECT *
    FROM dondh AS dh
    ORDER BY dh.ngaydh DESC
     
    -- Câu 7
    SELECT *
    FROM nhacc AS cc
    WHERE cc.manhacc NOT IN (SELECT dh.manhacc FROM dondh AS dh)
    
     
  • Hình đại diện của Không hiểu

    Viet nguyen van 1:32 pm on May 23, 2019 Liên kết tĩnh | Trả lời  

    Bài 3 – Các ràng buộc toàn vẹn dữ liệu 

    Các ràng buộc toàn vẹn dữ liệu

    Ràng buộc toàn vẹn dữ liệu là các quy tắc trong một cơ sở dữ liệu nhằm kiểm tra tính đúng đắn và hợp lệ của dữ liệu trước khi lưu trữ.


    Các quy định của công việc trong thực tế

    • Trong thực tế mỗi công việc đều có những quy định phải tuân theo
      • Mỗi quy định trở thành một hay nhiều ràng buộc trong CSDL
      • Một số quy định đơn giản, mặc nhiên thấy cũng phải mô tả trong CSDL
    • Ví dụ quản lý đơn đặt hàng
      • Số lượng đặt hàng phải lớn hơn 0
      • Các số hoá đơn giao hàng không được trùng nhau
      • Ngày dự kiến nhận hàng phải sau ngày đặt hàng
      • Một đơn đặt hàng phải do một khách hành lập ra
      • Mỗi một mặt hàng phải có nhà cung cấp (mỗi mặt hàng phải có xuất xứ)
      • Số lượng mặt hàng giao cho khách phải nhỏ hơn hay tối đa bằng với số lượng đặt
      • Hai nhà cung cấp có thể trùng tên nhưng là hai nhà cung cấp khác nhau

    Các ràng buộc toàn vẹn dữ liệu

    • SQL Server chia làm hai loại chính
      • Loại đơn giản: sử dụng CONSTRAINT để mô tả
      • Loại phức tạp: sử dụng TRIGGER để thực hiện
    • Các loại ràng buộc đơn giản
      • Kiểm tra duy nhất PRIMARY KEY, UNIQUE
      • Kiểm tra khác rỗng NOT NULL
      • Kiểm tra tồn tại FOREIGN KEY
      • Kiểm tra miền giá trị CHECK, DEFAULT

    Nguyên tắc chung

    • Một constraint luôn gắn với một bảng
    • Nếu không đặt tên thì hệ thống sẽ tự động phát sinh tên cho constraint.
    • Có thể tạo constraint :
      • Cùng với thời điểm tạo bảng hoặc
      • Sau khi đã tạo bảng xong
    • Có thể khai báo constraint ở mức cột hoặc mức bảng.
    • Có thể xem các constraint hiện có trong Database.

    Khai báo constraint

    CREATE TABLE [schema.]ten_bang
    (cot kieu_du_lieu [DEFAULT bieu_thuc]
    [constraint_muc_cot],
    ...
    [constraint_muc_bang][,...])
    

    Ví dụ constraint

    • Tên vật tư phải duy nhất 0<=
    • PhanTram <= 100
    • Giá trị mặc định cho cột đơn vị tính là “”
    ALTER TABLE vattu ADD
        CONSTRAINT chk_phantram CHECK (phantram BETWEEN 0 AND 100 ),
        CONSTRAINT u_tenvtu UNIQUE(tenvtu),
        CONSTRAINT d_dvtinh DEFAULT '' FOR dvtinh
    

    Khái niệm về mô hình quan hệ dữ liệu

    • Thể hiện mối quan hệ giữa các bảng trong CSDL
    • Có thể sử dụng để
      • Thiết lập mối quan hệ khoá ngoại (FOREIGN KEY)
      • Chỉnh sửa cấu trúc bảng
      • Chỉnh sửa thuộc tính bảng
      • Tạo bảng mới

    Ví dụ mô hình quan hệ

    ALTER TABLE ctpxuat
        ADD CONSTRAINT fk_ctpxuat_vattu FOREIGN KEY(mavtu) REFERENCES vattu(mavtu)
        ON DELETE CASCADE ON UPDATE CASCADE
        -- có 4 loại CASCADE, No Action, Set Null, Set Default
    
    Mô hình trong sql server
     
  • Hình đại diện của Không hiểu

    Viet nguyen van 11:16 am on May 23, 2019 Liên kết tĩnh | Trả lời
    Tags: , , ,   

    Bài 2 – Các đối tượng trong CSDL 

    Bài 2 – Các đối tượng trong CSDL

    Cùng tìm hiểu và cách tạo ra các đối tượng chính trong SQL: Database, Table, View … 


    Khái niệm về cơ sở dữ liệu

    • Database dùng để
      • Chứa các bảng, bảng ảo, thủ tục nội,…
      • Mỗi database có một danh sách các người dùng
        • Người dùng phải có quyền truy cập database
        • Có thể phân nhóm người dùng để cấp quyền
        • Tử phiên bản SQL Server 2000 hỗ trợ Application Role
    • Các database hệ thống Master, Model, Tempdb, msdb
    • Các database ví dụ AdventureWorks, AdventureWorkDWs
    Khái niệm về cơ sở dữ liệu

    Các tập tin vật lý lưu trữ cơ sở dữ liệu

    • Một database bao gồm tối thiểu hai file
      • .mdf: lưu trữ các đối tượng trong database như table, view, …
        • Có thể bổ sung thêm các tập tin lưu trữ khác
        • Tổ chức tốt các tập tin lưu trữ giúp tăng tốc độ xử lý
      • .ldf: lưu trữ quá trình cập nhật/thay đổi dữ liệu
        • Hỗ trợ phục hồi dữ liệu
        • Hỗ trợ backup/restore dữ liệu
    • Các thông số về kích thước
      • Initial size
      • File growth
      • Maximum file size
    sql server database engine

    Tạo database

    USE master
    GO
    --Nếu đã tồn tại database QLBanHang rồi thì xóa đi và tạo mới
    IF EXISTS (SELECT *  FROM MASTER.sys.DATABASES WHERE NAME=N'QLBanHang')
        --Xóa Database
        DROP DATABASE QLBanHang
    GO
    --Tạo database mới
    CREATE DATABASE QLBanHang
    

    Khái niệm về bảng

    • Bảng dùng để lưu trữ các thông tin của một đối tượng trong thực tế
      • Gồm có các dòng và các cột
      • Bảng trong CSDL thường có khoá chính (primary key)
      • Các bảng thường liên hệ với nhau bằng các mối quan hệ
      • Bảng được tạo trong các Schema (mặc định là schema dbo)
    • Bảng có thể có các ràng buộc (constraint), trigger

    Các thuộc tính của bảng

    • Tên bảng
    • Tên cột
    • Kiểu dữ liệu
      • Độ dài dữ liệu
      • Số ký số lưu trữ
      • Số số lẻ lưu trữ
    • Thuộc tính trên cột
      • Allow null
      • Identity
      • Default value

    Tạo cấu trúc bảng đơn giản

    CREATE TABLE Tên_schema.Tên_bảng
    (
    Tên_cột1 Kiểu_dữ_liệu [NOT NULL] ,
    Tên_cột2 Kiểu_dữ_liệu [NOT NULL] [, ...]
    )
    

    Ví dụ tạo bảng

    CREATE TABLE vattu
    (
        mavtu CHAR(4),
        tenvtu nvarchar(100) NOT NULL,
        dvtinh    nvarchar(10),
        phantram REAL,
        --Tạo khóa chính
        CONSTRAINT pk_vattu PRIMARY KEY(mavtu)
    )
    

    Khái niệm về bảng ảo

    • Được xây dựng từ câu truy vấn SELECT để hiển thị dữ liệu từ một hay nhiều bảng
      • Tập hợp dữ liệu, thể hiện cùng một dữ liệu nhưng theo nhiều cách khác nhau
      • Làm việc tương tự như một bảng nhưng không lưu trữ dữ liệu
      • Cho phép thêm/xoá/sửa
      • Bảo mật dữ liệu, bảo mật nội dung câu truy vấn dữ liệu
    • Một số hạn chế trong câu lệnh SELECT
      • Order By
      • Compute
      • Compute By

    Tạo mới bảng ảo bằng CREATE VIEW

    CREATE VIEW Tên_bảng_ảo
    [(Tên_các_cột)]
    [WITH ENCRYPTION]
    AS Câu_lệnh_SELECT
    [WITH CHECK OPTION]
    

    Ví dụ tạo bảng ảo

    CREATE VIEW vw_Vattu AS
    SELECT * FROM vattu
    

    Xem và cập nhật dữ liệu bảng ảo

    • Làm việc như một bảng thông thường sử dụng câu SELECT để xem dữ liệu Select * From vw_DonDH
    • Sử dụng INSERT/UPDATE để cập nhật dữ liệu
      • Chỉ có thể cập nhật vào một bảng
      • Để INSERT dữ liệu vào bảng, bảng ảo phải thỏa mãn các yêu cầu về khóa, ràng buộc khóa ngọai, các cột NOT NULL, các cột tính toán, order by, group by, distinct
    • Sử dụng Delete để xoá dữ liệu: bảng ảo tạo từ hai hay nhiều bảng không thể xoá
    • Có thể xây dựng các trigger trên bảng ảo

    Cập nhật dữ liệu qua bảng ảo sử dụng trigger INSTEAD OF

    • Bảng ảo có nhiều hạn chế khi thực hiện cập nhật dữ liệu
      • Group By, Order By, Distinct
      • Thiếu cột khoá
      • Ràng buộc toàn vẹn
    • SQL Server cung cấp loại trigger INSTEAD OF
      • Cơ chế tương tự như trigger thông thường
      • Mở rộng khả năng cập nhật, tính toán dữ liệu, đặc biệt với bảng ảo
      • Xem thêm phần TRIGGER

    Bài tập: Các đối tượng trong CSDL

    Tạo các đối tượng trong CSDL sau:

    Danh mục Vật Tư (VATTU)

    Tên cộtÝ nghĩaKiểuĐộ rộng
    MaVtuMã vật tưChar4
    TenVTuTên vật tưVarChar100
    DvTinhĐơn vị tínhVarChar10
    PhanTramTỷ lệ phần trămReal 
    create table vattu sql

    Danh mục Nhà Cung Cấp (NHACC)

    Tên cộtÝ nghĩaKiểuĐộ rộng
    MaNhaCCMã nhà cung cấpChar3
    TenNhaCCTên nhà cung cấpNVarChar100
    DiaChiĐịa chỉNVarChar200
    DienThoaiĐiện thoạiNVarChar20
    go
    create table nhacc
    (
    	manhacc char(3),
    	tennhacc	nvarchar(100) not null,
    	diachi	nvarchar(200),
    	dienthoai	nvarchar(20),
    	constraint pk_nhacc primary key(manhacc)
    )
    

    Đơn đặt hàng (DONDH)

    Tên cộtÝ nghĩaKiểuĐộ rộng
    SoDhSố đơn đặt hàngChar4
    NgayDhNgày đặt hàngDateTime 
    MaNhaCCMã nhà cung cấpChar3
    go
    create table dondh
    (
    	sodh char(4),
    	ngaydh	datetime,
    	manhacc char(3),
    	constraint pk_dondh primary key(sodh)
    )
    

    Chi tiết Đơn đặt hàng (CTDONDH)

    Tên cộtÝ nghĩaKiểuĐộ rộng
    SoDhSố đơn đặt hàngChar4
    MaVTuMã vật tưChar4
    SlDatSố lượng đặt hàngInt 
    GO
    CREATE TABLE ctdondh
    (
    	sodh CHAR(4),
    	mavtu	CHAR(4),
    	sldat INT,
    	CONSTRAINT pk_ctdondh PRIMARY KEY(sodh,mavtu)
    )
    

    Phiếu nhập hàng (PNHAP)

    Tên cộtÝ nghĩaKiểuĐộ rộng
    SoPnSố phiếu nhập hàngChar4
    NgayNhapNgày nhập hàngDatetime 
    SoDhSố đơn đặt hàngChar 
    go
    create table pnhap
    (
    	sopn	char(4) ,
    	ngaynhap datetime default  getdate(),--Ngày ngập sẽ bằng ngày hiện tại
    	sodh	char(4),
    	constraint pk_pnhap primary key(sopn)
    )
    

    Chi tiết nhập hàng (CTPNHAP)

    Tên cộtÝ nghĩaKiểuĐộ rộng
    SoPnSố phiếu nhập hàngChar4
    MaVTuMã vật tưChar4
    SlNhapSố lượng nhập hàngInt 
    DgNhapĐơn giá nhập hàngMoney 
    go
    create table ctpnhap
    (
    	sopn char(4),
    	mavtu	char(4),
    	slnhap int,
    	dgnhap	money,
    	constraint pk_ctpnhap primary key(sopn,mavtu)
    )
    

    Phiếu xuất hàng (PXUAT)

    Tên cộtÝ nghĩaKiểuĐộ rộng
    SoPxSố phiếu xuấtChar4
    NgayXuatNgày xuất hàngDatetime 
    TenKhTên khách hàngNVarchar100
    go
    create table pxuat
    (
    	sopx char(4),
    	ngayxuat	datetime default getdate(),--Ngày xuất bằng ngày hiện tại
    	tenkh	nvarchar(100),
    	constraint pk_pxuat primary key(sopx)
    )
    

    Chi tiết xuất hàng (CTPXUAT)

    Tên cộtÝ nghĩaKiểuĐộ rộng
    SoPxSố phiếu xuấtChar4
    MaVTuMã vật tưChar4
    SlXuatSố lượng xuất hàngInt 
    DgXuatĐơn giá xuất hàngMoney 
    go
    create table ctpxuat
    (
    	sopx char(4),
    	mavtu	char(4),
    	slxuat int,
    	dgxuat money,
    	constraint pk_ctpxuat primary key(sopx,mavtu)
    )
    

    Tồn kho (TONKHO)

    Tên cộtÝ nghĩaKiểuĐộ rộng
    NamThangNăm thángChar6
    MaVTuMã vật tưChar4
    SLDauSố lượng tồn đầu kỳInt 
    TongSLNTổng số lượng nhập trong kỳInt 
    TongSLXTổng số lượng xuất trong kỳInt 
    SLCuoiSố lượng tồn cuối kỳ, cột FormulaInt 
    GO
    CREATE TABLE tonkho
    (
    	namthang	CHAR(6),
    	mavtu	CHAR(4),
    	sldau	INT,
    	tongsln	INT,
    	tongslx	INT,
    	slcuoi AS sldau+tongsln-tongslx,
    	CONSTRAINT pk_tonkho PRIMARY KEY(namthang,mavtu)
    )
    

    Sử dụng câu lệnh INSERT INTO VALUES để thêm các mẩu tin vào bảng

    nhập dữ liệu cho bảng nhà cung cấp
    INSERT INTO nhacc
    VALUES('C01', N'Lê Minh Trí', N'54 Hậu Giang Q6 HCM' ,'8781024')
    INSERT INTO nhacc
    VALUES('C02', N'Trần Minh Thạch', N'145 Hùng Vương Mỹ Tho', '7698154')
    INSERT INTO nhacc
    VALUES('C03', N'Hồng Phương', N'154/85 Lê Lai Q1 HCM', '9600125')
    INSERT INTO nhacc
    VALUES('C04', N'Nhật Thắng', N'198/40 Hương Lộ 14 QTB HCM', '8757757')
    INSERT INTO nhacc
    VALUES('C05', N'Lưu Nguyệt Quế',N'178 Nguyễn Văn Luông Đà Lạt','7964251')
    INSERT INTO nhacc
    VALUES('C07',N'Cao Minh Trung', N'125 Lê Quang Sung Nha Trang', N'Chưa có')
    GO
    
    nhập dữ liệu cho bảng nhà cung vật tư
    --Table Vattu
    INSERT INTO vattu
    VALUES('DD01',N'Đầu DVD Hitachi 1 đĩa',N'Bộ','40')
    INSERT INTO vattu
    VALUES('DD02', N'Đầu DVD Hitachi 3 đĩa', N'Bộ','40')
    INSERT INTO vattu
    VALUES('TL15', N'Tủ lạnh Sanyo 150 lit', N'Cái', '25')
    INSERT into vattu
    VALUES('TL90', N'Tủ lạnh Sanyo 90 lit', N'Cái', '20')
    INSERT INTO vattu
    VALUES('TV14', N'Tivi Sony 14 inches', N'Cái', '15')
    INSERT INTO vattu
    VALUES('TV21', N'Tivi Sony 21 inches', N'Cái', '10')
    INSERT INTO vattu
    VALUES('TV29' ,N'Tivi Sony 29 inches', 'Cái' ,'10')
    INSERT INTO vattu
    VALUES('VD01', N'Đầu VCD Sony 1 đĩa',N'Bộ', '30')
    INSERT INTO vattu
    VALUES('VD02',N'Đầu VCD Sony 3 đĩa', N'Bộ', '30')
    GO
    
    nhập dữ liệu cho bảng đơn đặt hàng và phiếu nhập
    --Table Dondh
    INSERT INTO dondh
    VALUES('D001', '01/15/2009', 'C03')
    INSERT INTO dondh
    VALUES('D002', '01/30/2009', 'C01')
    INSERT INTO dondh
    VALUES('D003' ,'02/10/2009' ,'C02')
    INSERT INTO dondh
    VALUES('D004', '02/17/2009' ,'C05')
    INSERT INTO dondh
    VALUES('D005' ,'03/01/2009', 'C02')
    INSERT INTO dondh
    VALUES('D006', '03/12/2009' ,'C05')
    GO
    
    
    --Table Pnhap
    INSERT INTO pnhap
    VALUES('N001', '01/17/2009', 'D001')
    INSERT INTO pnhap
    VALUES('N002', '01/20/2009', 'D001')
    INSERT INTO pnhap
    VALUES('N003', '01/31/2009', 'D002')
    INSERT INTO pnhap
    VALUES('N004','02/15/2009', 'D003')
    GO
    
    nhập dữ liệu cho bảng chi tiết đơn đặt hàng và chi tiết phiếu nhập
    --Table ctdondh
    INSERT INTO ctdondh
    VALUES('D001', 'DD01', '10')
    INSERT INTO ctdondh
    VALUES('D001' ,'DD02' ,'15')
    INSERT INTO ctdondh
    VALUES('D002' ,'VD02', '30')
    INSERT INTO ctdondh
    VALUES('D003' ,'TV14' ,'10')
    INSERT INTO ctdondh
    VALUES('D003' ,'TV29', '20')
    INSERT INTO ctdondh
    VALUES('D004' ,'TL90' ,'10')
    INSERT INTO ctdondh
    VALUES('D005' ,'TV14', '10')
    INSERT INTO ctdondh
    VALUES('D005', 'TV29' ,'20')
    INSERT INTO ctdondh
    VALUES('D006' ,'TV14', '10')
    INSERT INTO CTDONDH
    VALUES('D006' ,'TV29' ,'20')
    INSERT INTO CTDONDH
    VALUES('D006' ,'VD01' ,'20')
    GO
    
    
    --Table ctpnhap
    INSERT INTO ctpnhap
    VALUES('N001', 'DD01', '8' ,'2,500,000')
    INSERT INTO ctpnhap
    VALUES('N001' ,'DD02' ,'10' ,'3,500,000')
    INSERT INTO ctpnhap
    VALUES('N002', 'DD01', '2', '2,500,000')
    INSERT INTO ctpnhap
    VALUES('N002' ,'DD02' ,'5', '3,500,000')
    INSERT INTO ctpnhap
    VALUES('N003', 'VD02', '30', '2,500,000')
    INSERT INTO ctpnhap
    VALUES('N004', 'TV14', '5', '2,500,000')
    INSERT INTO ctpnhap
    VALUES('N004' ,'TV29' ,'12', '3,500,000')
    GO
    
    
    nhập dữ liệu cho bảng phiếu xuất
    --Table pxuat
    INSERT INTO pxuat
    VALUES('X001', '01/17/2009', N'Nguyễn Ngọc Phương Nhi')
    INSERT INTO pxuat
    VALUES('X002', '01/25/2009', N'Nguyễn Hồng Phương')
    INSERT INTO pxuat
    VALUES('X003', '01/31/2009', N'Nguyễn Tuấn Tú')
    GO
    
    nhập dữ liệu cho bảng chi tiết phiếu xuất
    --Table ctpxuat
    INSERT INTO ctpxuat
    VALUES('X001', 'DD01', '2', '3,500,000')
    INSERT INTO ctpxuat
    VALUES('X002' ,'DD01', '1' ,'3,500,000')
    INSERT INTO ctpxuat
    VALUES('X002' ,'DD02', '5', '4,900,000')
    INSERT INTO ctpxuat
    VALUES('X003', 'DD01' ,'3' ,'3,500,000')
    INSERT INTO ctpxuat
    VALUES('X003' ,'DD02', '2', '4,900,000')
    INSERT INTO ctpxuat
    VALUES('X003' ,'VD02', '10' ,'3,250,000')
    GO
    
    
    nhập dữ liệu cho bảng tồn kho
    --Table tonkho
    INSERT INTO tonkho
    VALUES('200901' ,'DD01', '0', '10', '6')
    INSERT INTO tonkho(namthang,mavtu,sldau,tongsln,tongslx)
    VALUES('200901', 'VD02', '0' ,'30' ,'10' )
    INSERT INTO tonkho(namthang,mavtu,sldau,tongsln,tongslx)
    VALUES('200902', 'DD01' ,'4' ,'0', '0')
    INSERT INTO tonkho(namthang,mavtu,sldau,tongsln,tongslx)
    VALUES('200902', 'DD02' ,'8' ,'0', '0' )
    INSERT INTO tonkho(namthang,mavtu,sldau,tongsln,tongslx)
    VALUES('200901' ,'DD02', '0', '15' ,'7' )
    INSERT INTO tonkho(namthang,mavtu,sldau,tongsln,tongslx)
    VALUES('200902', 'VD02', '20', '0' ,'0' )
    INSERT INTO tonkho(namthang,mavtu,sldau,tongsln,tongslx)
    VALUES('200902', 'TV14', '5', '0', '0')
    INSERT INTO tonkho(namthang,mavtu,sldau,tongsln,tongslx)
    VALUES('200902', 'TV29' ,'12' ,'0', '0' )
    GO
    

    Đối tượng bảng ảo (view)

    • Tạo view có tên vw_CTPNHAP bao gồm các thông tin sau: số phiếu nhập hàng, mã vật tư, số
      lượng nhập, đơn giá nhập, thành tiền nhập 
    • Tạo view có tên vw_CTPNHAP_VT bao gồm các thông tin sau: số phiếu nhập hàng, mã vật tư, tên vật tư, số lượng nhập, đơn giá nhập, thành tiền nhập
    • Tạo view có tên vw_CTPNHAP_VT_PN bao gồm các thông tin sau: số phiếu nhập hàng, ngày nhập hàng, số đơn đặt hàng, mã vật tư, tên vật tư, số lượng nhập, đơn giá nhập, thành tiền nhập
    • Tạo view có tên vw_CTPNHAP_VT_PN_DH bao gồm các thông tin sau: số phiếu nhập hàng, ngày nhập hàng, số đơn đặt hàng, mã nhà cung cấp, mã vật tư, tên vật tư, số lượng nhập, đơn giá nhập, thành tiền nhập
    • Tạo view có tên vw_CTPNHAP_loc bao gồm các thông tin sau: số phiếu nhập hàng, mã vật tư, số lượng nhập, đơn giá nhập, thành tiền nhập. Và chỉ liệt kê các chi tiết nhập có số lượng nhập > 5
    • Tạo view có tên vw_CTPNHAP_VT_loc bao gồm các thông tin sau: số phiếu nhập hàng, mã vật tư, tên vật tư, số lượng nhập, đơn giá nhập, thành tiền nhập. Và chỉ liệt kê các chi tiết nhập vật tư có đơn vị tính là Bộ
    • Tạo view có tên vw_CTPXUAT bao gồm các thông tin sau: số phiếu xuất hàng, mã vật tư, số lượng xuất, đơn giá xuất, thành tiền xuất
    • Tạo view có tên vw_CTPXUAT_VT bao gồm các thông tin sau: số phiếu xuất hàng, mã vật tư, tên vật tư, số lượng xuất, đơn giá xuất
    • Tạo view có tên vw_CTPXUAT_VT_PX bao gồm các thông tin sau: số phiếu xuất hàng, tên khách hàng, mã vật tư, tên vật tư, số lượng xuất, đơn giá xuất
    • Sửa view vw_CTPXUAT_VT_PX để bổ sung thêm cột thành tiền xuất
    • Xem nội dung câu lệnh SELECT của view vw_CTPXUAT
    • Xoá view vw_CTPXUAT
     
  • Hình đại diện của Không hiểu

    Viet nguyen van 11:04 am on May 23, 2019 Liên kết tĩnh | Trả lời
    Tags: , Chung, , ,   

    Bài 1 – Tổng quan về SQL Server 

    Tổng quan về SQL Server

    SQL Server là một hệ quản trị cơ sở dữ liệu quan hệ (Relational Database Management System (RDBMS) ) sử dụng câu lệnh SQL (Transact-SQL) để trao đổi dữ liệu giữa máy Client và máy cài SQL Server


    Khái niệm về cấu trúc vật lý

    • Máy chủ (Server)
    • Máy trạm (Client): là các máy tính được phép truy xuất các tài nguyên đã được chia sẻ trên mạng.
    • Dây cáp mạng (Cable hoặc Media): là một hệ thống dây cáp nối kết vật lý các máy tính, máy in lại với nhau
    • Dữ liệu chung (Shared data): là các tập tin, thư mục mà người sử dụng trong hệ thống mạng có thể truy xuất vào máy chủ từ các máy trạm
    Khái niệm về cấu trúc vật lý của cơ sở dữ liệu SQL

    Khái niệm về các xử lý

    • Các xử lý trong một ứng dụng có thể chia làm hai loại xử lý trên máy trạm và xử lý trên máy chủ
    • Xử lý trên máy trạm
      • Đọc, cập nhật dữ liệu
      • Tính toán, hiển thị dữ liệu trên màn hình giao diện
      • Có thể sử dụng nhiều loại ngôn ngữ lập trình khác nhau: Java, C#…
    • Xử lý trên máy chủ Database Server
      • Xử lý các yêu cầu đọc/ghi dữ liệu
      • Quản lý đồng bộ dữ liệu giữa các yêu cầu đọc ghi từ nhiều máy trạm gửi tới
      • Các dịch vụ quản trị dữ liệu tự động theo định kỳ như backup/restore dữ liệu

    Vì sao phát triển ứng dụng khách chủ?

    • Giảm chi phí
      • Chia sẻ tài nguyên phần cứng/phần mềm
      • Giảm chi phí bản quyền
      • Giảm chi phí nâng cấp, bảo trì, quản lý
    • Tốc độ nhanh: Các xử lý phức tạp có thể thực hiện tại server
    • Tính tương thích cao: Nhiều công cụ lập trình được hỗ trợ bởi phần mềm làm việc trên máy chủ

    Lịch sử ra đời Microsoft SQL Server

    • 1970: IBM giới thiệu ngôn ngữ SEQUEL
    • 1987: IBM tích hợp phần mềm quản trị CSDL vào hệ điều hành OS2
    • 1988: Hệ quản trị CSDL Ashton-Tate được MS kết hợp với Sybase giới thiệu
    • MS bắt đầu phát triển SQL Server trên nền Ashton-Tate và đưa vào WinNT Server sau đó
    • Các phiên bản được sử dụng của SQL Server: 4.2, 4.21, 6.0, 6.5, 7.0, 2000, 2005, 2008, 2010, 2012, 2012, 2014, 2016

    OLTP và OLAP

    • OLTP Databases (online transaction processing): SQL Server cho phép nhiều người dùng thực hiện đồng thời các giao tác và dữ liệu thay đổi theo thời gian thực
    • OLAP Databases (online analytical processing): Công nghệ OLAP tổ chức và thống kê khối lượng lớn dữ liệu được dùng để phân tích, báo cáo, hổ trợ ra quyết định

    Cài Đặt SQL Server

    Xem tại đây

    Các tiện ích trong Microsoft SQL Server

    • Tiện ích SQL Server Management Studio cho phép quản trị Cơ sở dữ liệu bằng giao diện đồ họa
      • Quản trị các thể hiện
      • Quản trị các đối tượng
      • Sử dụng Query Window để thực hiện các câu lệnh
    • Tiện ích Book Online toàn bộ các tài liệu liên quan đến SQL Server
    • Tiện ích SQL Server Configuration Manager Cấu hình hệ thống
     
c
Compose new post
j
Next post/Next comment
k
Previous post/Previous comment
r
Trả lời
e
Sửa
o
Show/Hide comments
t
Chuyển lên trên
l
Go to login
h
Show/Hide help
shift + esc
Hủy bỏ
Tạo trang giống vầy với WordPress.com
Hãy bắt đầu