Tôi có nên kiểm tra sự tồn tại của các bảng tạm thời trong Thủ tục lưu trữ không?


7

Có trường hợp cạnh nào trong đó sẽ được khuyến nghị kiểm tra rõ ràng, thả và tạo các bảng tạm thời khi bắt đầu Thủ tục lưu trữ thay vì chỉ tạo chúng không?

Tương tự như vậy, có trường hợp nào khi bỏ chúng một cách rõ ràng vào cuối Quy trình được lưu trữ thì tốt hơn là để SQL Server dọn sạch chúng không?

Câu trả lời:


7

Đang kiểm tra #tbl

Nó không thể bị tổn thương để kiểm tra sự tồn tại của bảng (và thả nó nếu nó tồn tại) vào đầu các thủ tục, nhưng nó phụ thuộc vào cách bạn muốn xử lý kịch bản đó, và trong nhiều trường hợp nó không thể cho nó tồn tại đã dù sao đi nữa (ít nhất là nếu chúng ta đang nói về cùng một bảng #temp như được định nghĩa trong quy trình được lưu trữ đó).

Bạn kiểm tra sự tồn tại của bảng bằng cách sử dụng:

IF OBJECT_ID('tempdb..#tablename') IS NOT NULL

Bạn không thể kiểm tra tempdb.sys.tables vì ​​tên thực tế là #tablename__________some hex codevà bạn không nên sử dụng OBJECT_ID('...') > 0 vì vấn đề tiềm ẩn này .

Tất nhiên, có những trường hợp ngoại lệ. Hai điều đó đến với tâm trí:

  • nếu bạn gọi tất cả mọi thứ #temp, hoặc #t, hoặc #x, thì có thể một bảng như vậy đã tồn tại từ một phạm vi bên ngoài trước khi gọi thủ tục. Bạn có thể tạo ra một trường hợp mà bạn nên bỏ nó và tạo một cái mới trong trường hợp đó, nhưng bạn cũng có thể tạo ra một trường hợp rằng đây là một điều kiện lỗi bạn muốn biết - vì vậy có thể nó không CREATE TABLE #xthành công.

  • bạn thực sự có thể muốn sử dụng bảng #temp được tạo trong phạm vi bên ngoài và chỉ tạo một bảng nếu nó chưa được xác định trong phạm vi bên ngoài đó. Điều này là có thể và tôi sử dụng kỹ thuật này mọi lúc, nhưng thường chỉ khi tôi muốn thu thập dữ liệu từ các quy trình hệ thống mà tôi không thể dễ dàng tự thao tác (ví dụ sp_helptext). Vì vậy, tôi có thể làm điều này:

    CREATE TABLE #x([Text] NVARCHAR(MAX));
    GO
    CREATE PROCEDURE dbo.myhelp @p SYSNAME
    AS
      INSERT #x EXEC sp_helptext @p;
    GO
    EXEC dbo.myhelp N'dbo.myhelp'; -- inception
    GO
    SELECT [Text] FROM #x;
    

    Điều này hoạt động mặc dù #xđược xác định bên ngoài. Đó là một ví dụ tồi tệ bởi vì tôi thích sử dụng hơn sys.sql_modules, nhưng tôi chắc chắn rằng bạn hiểu rõ và có thể hình dung bạn có thể làm điều đó bằng các thủ tục của riêng bạn như thế nào.

Trên BẢNG DROP #tbl;

Tôi nghĩ rằng liệu bạn có nên bỏ các bảng #temp một cách rõ ràng vào cuối quy trình hay không là rất nhiều tranh luận, và do đó sẽ bị đóng cửa vì chủ yếu dựa trên quan điểm; xem những bài đăng trên blog tuyệt vời này của Paul White , đọc chúng kỹ lưỡng và quay lại và đặt ra một câu hỏi cụ thể nếu tất cả các bạn không trả lời:


2

Tôi nghĩ rằng nó sẽ phụ thuộc vào cách bạn đang sử dụng bảng tạm thời. Nếu SELECT INTOđang được sử dụng, tôi sẽ kiểm tra trước và dropcuối cùng. Kiểm tra trước khi thả và thả sẽ ngăn chặn các sự cố không mong muốn trên đường có thể hoặc không thể leo lên, đó chỉ là thực hành mã tốt với tôi.

Nếu bạn đang sử dụng CREATE TABLEđể tạo bảng tạm thời trước tiên, tôi nghĩ rằng tôi sẽ làm điều tương tự theo thói quen và cố gắng giữ một tiêu chuẩn như cách tôi xây dựng các quy trình. Với điều này, bạn có thể nhận được bằng cách chỉ có câu lệnh thả ở cuối quy trình, đã thấy mã được thực hiện chỉ với các giọt ở cuối.

Nếu bạn ở trong một nhóm, hoặc thậm chí nếu đó chỉ là bạn, hãy đưa ra một tiêu chuẩn và tuân thủ nó.

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.