2012-09-21 54 views
19

Có ai thấy điều gì sai với mã này cho SQL Server không?Tên cột không hợp lệ trên bản cập nhật máy chủ sql sau khi tạo cột

IF NOT EXISTS(SELECT * 
       FROM sys.columns 
       WHERE Name = 'OPT_LOCK' 
        AND object_ID = Object_id('REP_DSGN_SEC_GRP_LNK')) 
    BEGIN 
     ALTER TABLE REP_DSGN_SEC_GRP_LNK 
     ADD OPT_LOCK NUMERIC(10, 0) 

     UPDATE REP_DSGN_SEC_GRP_LNK 
     SET OPT_LOCK = 0 

     ALTER TABLE REP_DSGN_SEC_GRP_LNK 
     ALTER COLUMN OPT_LOCK NUMERIC(10, 0) NOT NULL 
    END; 

Khi tôi chạy này, tôi nhận được:

Msg 207, Level 16, State 1, Line 3
tên cột không hợp lệ 'OPT_LOCK'.

trên lệnh cập nhật.

Cảm ơn.

Trả lời

33

Trong trường hợp này, bạn có thể tránh sự cố bằng cách thêm cột dưới dạng NOT NULL và đặt giá trị cho các hàng hiện tại trong một tuyên bố as per my answer here.

Thông thường, sự cố là vấn đề phân tích cú pháp/biên dịch. SQL Server cố gắng biên dịch tất cả các câu lệnh trong lô trước khi thực hiện bất kỳ câu lệnh nào.

Khi một câu lệnh tham chiếu đến một bảng không tồn tại ở tất cả các câu lệnh thì phải chịu sự biên dịch trì hoãn. Khi bảng đã tồn tại nó ném một lỗi nếu bạn tham chiếu một cột không tồn tại. Cách tốt nhất là làm DDL trong một lô khác với DML.

Nếu một câu lệnh cả tham chiếu cột không tồn tại trong bảng hiện có và bảng không tồn tại, lỗi có thể hoặc không thể được ném trước khi biên dịch được hoãn lại.

Bạn có thể gửi theo lô riêng biệt (ví dụ: bằng cách sử dụng công cụ tách hàng loạt GO trong công cụ khách hàng) hoặc thực hiện nó trong phạm vi con được biên dịch riêng biệt bằng cách sử dụng EXEC hoặc EXEC sp_executesql.

Cách tiếp cận đầu tiên sẽ yêu cầu bạn phải cấu trúc lại mã của mình dưới dạng IF ... không thể chia lô.

IF NOT EXISTS(SELECT * 
       FROM sys.columns 
       WHERE Name = 'OPT_LOCK' 
        AND object_ID = Object_id('REP_DSGN_SEC_GRP_LNK')) 
    BEGIN 
     ALTER TABLE REP_DSGN_SEC_GRP_LNK 
     ADD OPT_LOCK NUMERIC(10, 0) 

     EXEC('UPDATE REP_DSGN_SEC_GRP_LNK SET OPT_LOCK = 0'); 

     ALTER TABLE REP_DSGN_SEC_GRP_LNK 
     ALTER COLUMN OPT_LOCK NUMERIC(10, 0) NOT NULL 
    END; 
+1

EXEC đã tiếp cận với tôi. Cảm ơn! – feradz

+0

Đây là cách tiếp cận tôi đã sử dụng trong nhiều năm, và nó luôn làm tôi ngạc nhiên khi chúng tôi buộc phải thực hiện tuyến đường sql động bất tiện này bất cứ khi nào chúng tôi muốn thêm cột mới và điền dữ liệu vào ... –

0

Để biết thông tin của bạn, bạn có thể thay thế các IF NOT EXISTS với COL_LENGTH chức năng. Phải mất hai tham số,

  1. Bảng Tên và

  2. Cột bạn đang tìm kiếm

Nếu Cột được tìm thấy sau đó nó sẽ trả về phạm vi của kiểu dữ liệu của cột Ex: Int (4 byte), khi không tìm thấy thì nó trả về một NULL.

Vì vậy, bạn có thể sử dụng điều này như sau và cũng kết hợp 3 Câu lệnh thành một.

IF (SELECT COL_LENGTH('REP_DSGN_SEC_GRP_LNK','OPT_LOCK')) IS NULL 

BEGIN 

    ALTER TABLE REP_DSGN_SEC_GRP_LNK 
    ADD OPT_LOCK NUMERIC(10, 0) NOT NULL DEFAULT 0 

END; 

Làm cho nó đơn giản hơn.

Các vấn đề liên quan