Tương tự như đề xuất của @ David để đưa dữ liệu vào bảng "tiến trình", nhưng không cần phải gây rối với các vấn đề dọn dẹp hoặc đồng thời / phân tách quy trình:
- Tạo một cái mới
Guid
trong mã ứng dụng và chuyển nó dưới dạng tham số cho Thủ tục lưu trữ. Lưu trữ Hướng dẫn này trong một biến vì nó sẽ được sử dụng nhiều lần.
- Trong Quy trình được lưu trữ, tạo Bảng tạm thời toàn cầu bằng cách sử dụng Hướng dẫn đó làm một phần của tên bảng, đại loại như thế
CREATE TABLE ##MyProcess_{GuidFromApp};
. Bảng có thể có bất kỳ cột nào của bất kỳ kiểu dữ liệu nào bạn cần.
Bất cứ khi nào bạn có dữ liệu, hãy chèn nó vào Bảng tạm thời toàn cầu đó.
Trong mã ứng dụng, bắt đầu cố gắng để đọc dữ liệu, nhưng quấn SELECT
trong một IF EXISTS
vì vậy nó sẽ không thất bại nếu bảng chưa được nào được tạo:
IF (OBJECT_ID('tempdb..[##MyProcess_{0}]')
IS NOT NULL)
BEGIN
SELECT * FROM [##MyProcess_{0}];
END;
Với String.Format()
, bạn có thể thay thế {0}
bằng giá trị trong biến Guid. Kiểm tra xem nếu Reader.HasRows
và nếu đúng thì đọc kết quả, gọi khác Thread.Sleep()
hoặc bất cứ điều gì để thăm dò lại.
Những lợi ích:
- Bảng này được phân lập từ các quy trình khác vì chỉ có mã ứng dụng biết giá trị Hướng dẫn cụ thể, do đó không cần phải lo lắng về các quy trình khác. Một quá trình khác sẽ có bảng tạm thời toàn cầu riêng của mình.
- Bởi vì nó là một cái bàn, mọi thứ đều được gõ mạnh.
- Vì là bảng tạm thời, khi phiên thực hiện Quy trình được lưu trữ kết thúc, bảng sẽ tự động được dọn sạch.
- Bởi vì nó là một bảng tạm thời toàn cầu :
- các phiên khác có thể truy cập được, giống như một bảng cố định
- nó sẽ tồn tại đến cuối của quá trình phụ được tạo ra (tức là
EXEC
/ sp_executesql
gọi)
Tôi đã thử nghiệm điều này và nó hoạt động như mong đợi. Bạn có thể tự thử nó với mã ví dụ sau.
Trong một tab truy vấn, hãy chạy như sau, sau đó tô sáng 3 dòng trong nhận xét khối và chạy:
CREATE
--ALTER
PROCEDURE #GetSomeInfoBackQuickly
(
@MessageTableName NVARCHAR(50) -- might not always be a GUID
)
AS
SET NOCOUNT ON;
DECLARE @SQL NVARCHAR(MAX) = N'CREATE TABLE [##MyProcess_' + @MessageTableName
+ N'] (Message1 NVARCHAR(50), Message2 NVARCHAR(50), SomeNumber INT);';
-- Do some calculations
EXEC (@SQL);
SET @SQL = N'INSERT INTO [##MyProcess_' + @MessageTableName
+ N'] (Message1, Message2, SomeNumber) VALUES (@Msg1, @Msg2, @SomeNum);';
DECLARE @SomeNumber INT = CRYPT_GEN_RANDOM(2);
EXEC sp_executesql
@SQL,
N'@Msg1 NVARCHAR(50), @Msg2 NVARCHAR(50), @SomeNum INT',
@Msg1 = N'wow',
@Msg2 = N'yadda yadda yadda',
@SomeNum = @SomeNumber;
WAITFOR DELAY '00:00:10.000';
SET @SomeNumber = CRYPT_GEN_RANDOM(3);
EXEC sp_executesql
@SQL,
N'@Msg1 NVARCHAR(50), @Msg2 NVARCHAR(50), @SomeNum INT',
@Msg1 = N'wow',
@Msg2 = N'yadda yadda yadda',
@SomeNum = @SomeNumber;
WAITFOR DELAY '00:00:10.000';
GO
/*
DECLARE @TempTableID NVARCHAR(50) = NEWID();
RAISERROR('%s', 10, 1, @TempTableID) WITH NOWAIT;
EXEC #GetSomeInfoBackQuickly @TempTableID;
*/
Chuyển đến tab "Tin nhắn" và sao chép GUID đã được in. Sau đó, mở một tab truy vấn khác và chạy như sau, đặt GUID mà bạn đã sao chép từ tab Tin nhắn của Phiên khác vào khởi tạo biến trên dòng 1:
DECLARE @TempTableID NVARCHAR(50) = N'GUID-from-other-session';
EXEC (N'SELECT * FROM [##MyProcess_' + @TempTableID + N']');
Tiếp tục đánh F5. Bạn sẽ thấy 1 mục trong 10 giây đầu tiên, và sau đó 2 mục trong 10 giây tiếp theo.