Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Bảng tổng hợp SQL là chỉ đọc và không thể chỉnh sửa các ô?

Giả sử bạn có một ràng buộc duy nhất đối với n_id, field có nghĩa là ít nhất một hàng có thể khớp, bạn có thể (trên lý thuyết là ít nhất) sử dụng INSTEAD OF Kích hoạt.

Điều này sẽ dễ dàng hơn với MERGE (nhưng điều đó không khả dụng cho đến SQL Server 2008) vì bạn cần phải bao gồm UPDATES dữ liệu hiện có, INSERTS (Trường hợp NULL giá trị được đặt thành NON NULL một) và DELETES trong đó NON NULL giá trị được đặt thành NULL .

Một điều bạn cần cân nhắc ở đây là cách đối phó với UPDATES đặt tất cả các cột trong một hàng thành NULL Tôi đã làm điều này trong khi kiểm tra mã bên dưới và khá bối rối trong một hoặc hai phút cho đến khi tôi nhận ra rằng điều này đã xóa tất cả các hàng trong bảng cơ sở cho một n_id (có nghĩa là thao tác này không thể hoàn nguyên qua UPDATE khác bản tường trình). Có thể tránh được vấn đề này bằng cách sử dụng định nghĩa VIEW OUTER JOIN lên bảng nào n_id là PK của.

Dưới đây là một ví dụ về loại điều này. Bạn cũng cần phải xem xét các điều kiện chủng tộc tiềm năng trong INSERT / DELETE mã được chỉ ra và liệu bạn có cần thêm một số gợi ý khóa trong đó hay không.

CREATE TRIGGER trig
ON pivoted
INSTEAD OF UPDATE
AS
  BEGIN
      SET nocount ON;

      DECLARE @unpivoted TABLE (
        n_id             INT,
        field            VARCHAR(10),
        c_metadata_value VARCHAR(10))

      INSERT INTO @unpivoted
      SELECT *
      FROM   inserted UNPIVOT (data FOR col IN (fid, sid, NUMBER) ) AS unpvt
      WHERE  data IS NOT NULL

      UPDATE m
      SET    m.c_metadata_value = u.c_metadata_value
      FROM   metadata m
             JOIN @unpivoted u
               ON u.n_id = m.n_id
                  AND u.c_metadata_value = m.field;

      /*You need to consider race conditions below*/
      DELETE FROM metadata
      WHERE  NOT EXISTS(SELECT *
                        FROM   @unpivoted u
                        WHERE  metadata.n_id = u.n_id
                               AND u.field = metadata.field)

      INSERT INTO metadata
      SELECT u.n_id,
             u.field,
             u.c_metadata_value
      FROM   @unpivoted u
      WHERE  NOT EXISTS (SELECT *
                         FROM   metadata m
                         WHERE  m.n_id = u.n_id
                                AND u.field = m.field)
  END  


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm thế nào để bắt SqlException gây ra bởi deadlock?

  2. Tại sao tùy chọn lập chỉ mục Toàn văn bản lại có màu xám?

  3. Lỗi khi chèn giá trị có dấu nháy đơn

  4. Tại sao một hàm T-SQL UDF đơn giản lại làm cho việc thực thi mã chậm hơn 3 lần

  5. Duy trì cột ngày giờ được tính toán trong SQL Server 2005