Đây có phải là hợp pháp và để tạo ra và tạo ra #SomeTable nhiều lần không?


8

Tôi đã có loại mã được tách riêng thành "khối kết hợp" mà tôi có thể chèn vào "tập lệnh cấu hình" dài hơn và một trong những mẫu tôi đang sử dụng là:

CREATE TABLE #WidgetSetting 
(
    WidgetID bigint not null,
    Name nvarchar(100) not null,
    Value nvarchar(max) not null,
    CreateDate datetime not null
)

INSERT VALUES

MERGE TABLES

DROP TABLE #WidgetSetting

Nhưng bây giờ SSMS đang phàn nàn rằng đối tượng đã tồn tại vào lần tiếp theo CREATE TABLE. Đưa cái gì?

Tôi nghĩ rõ ràng là tôi sẽ phải khai báo bảng một lần khi bắt đầu tập lệnh, cắt ngắn thay vì thả, nhưng thật bực bội, không thể bỏ bảng và sử dụng lại tên đó một lần nữa.


Như Aaron đã nhận xét bên dưới, nếu đây là tuyến đường bạn đã thực hiện, cách khắc phục dễ dàng nhất có thể là bỏ #TABLE ở phần cuối của tập lệnh và chỉ cần TRUNCATE theo các bước giữa. Điều đó giả định rằng không thể chỉ thiết kế lại tập lệnh để hoạt động khác đi ngay từ đầu. :)
Kahn

1
Đó thực sự là những gì tôi đã làm để giải quyết nó. Tôi chỉ bối rối bởi hành vi. Ông giải thích lý do tại sao đó là điều tôi muốn nhiều hơn là cách khắc phục nó.
jcolebrand

Câu trả lời:


11

Không, trình phân tích cú pháp sẽ không cho phép bạn tạo cùng một bảng #temp hai lần trong cùng một đợt (và điều này không liên quan gì đến SSMS). Nó thậm chí không quan trọng nếu chỉ có một bản sao của bảng #temp có thể được tạo; ví dụ, trong logic có điều kiện sau đây, mà đối với con người rõ ràng chỉ có thể thực thi một nhánh, SQL Server không thể thấy rằng:

IF 1 = 1
BEGIN
  CREATE TABLE #x(i INT);
  DROP TABLE #x;
END
ELSE
BEGIN
  CREATE TABLE #x(j INT);
  DROP TABLE #x;
END

Msg 2714, Cấp 16, Trạng thái 1, Dòng 8
Đã có một đối tượng có tên '#x' trong cơ sở dữ liệu.

Và để chứng minh rằng SSMS không phàn nàn tại thời điểm biên dịch (một quan niệm sai lầm phổ biến):

DECLARE @sql NVARCHAR(MAX) = N'IF 1 = 1
BEGIN
  CREATE TABLE #x(i INT);
  DROP TABLE #x;
END
ELSE
BEGIN
  CREATE TABLE #x(j INT);
  DROP TABLE #x;
END';

EXEC sp_executesql @sql;

Mang lại cùng một lỗi chính xác, mặc dù SSMS không cố phân tích hoặc xác thực SQL động trước khi gửi nó đến máy chủ thông qua sp_executesql.

Tất nhiên, cách khắc phục là sử dụng lại cùng một bảng #temp thay vì bỏ, sử dụng một bảng #temp khác nhau mỗi lần hoặc không sử dụng các bảng #temp ở vị trí đầu tiên.

Đây không phải là điều bạn nên mong đợi SQL Server sẽ xử lý tốt hơn. Nói cách khác, hãy làm quen với bất kỳ cách giải quyết nào mà bạn quyết định.

Xem thêm câu trả lời liên quan này trên Stack Overflow để đưa ra lời giải thích thay thế:

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.