2010-11-03 36 views
6

Tôi gần như đã hoàn tất việc thay đổi thủ tục được lưu trữ dựa trên con trỏ thành dựa trên tập hợp. Hầu như, bởi vì tôi chỉ còn một điều để tìm ra.Câu lệnh UPDATE sử dụng EXEC để thực thi một thủ tục đã lưu để SET một giá trị cột

Chúng sử dụng thủ tục được lưu trữ được gọi là GetSequence để truy vấn bảng, cập nhật bảng bằng số thứ tự mới (cũ + 1) và trả về giá trị số thứ tự mới. Đây không phải là vấn đề khi họ sử dụng con trỏ vì chúng đã gán giá trị đầu ra cho một biến, sau đó sử dụng biến.

Cách duy nhất tôi có thể nghĩ để giữ bộ quy trình được lưu trữ mới dựa trên là thực thi GetSequence trong câu lệnh INSERT hoặc UPDATE. Tuy nhiên, tôi nhận được lỗi tuyệt vời cụ thể đó, "cú pháp sai gần từ khóa 'EXEC'", khi tôi thử điều đó.

Đây là mã cũ:

DECLARE @new_UD_campaignID BIGINT -- Get the new ud_lead_id for the new lead set 
    EXEC ppGlobal.dbo.Getsequence 
    'ud_campaign_id', 
    @new_UD_campaignID OUTPUT 
    DECLARE @OrderNum VARCHAR(9); 
    IF @corpCamp LIKE '%LEP%' 
    BEGIN 
     SELECT @OrderNum = ('L' + RIGHT('00000000' + CAST(@new_UD_campaignID AS VARCHAR(8)), 8)) 
    END 
    ELSE 
    BEGIN 
     SELECT @OrderNum = ('C' + RIGHT('00000000' + CAST(@new_UD_campaignID AS VARCHAR(8)), 8)) 
    END 

này hoạt động, nhưng là rất chậm vì nó nằm trong một con trỏ và cập nhật hơn hai triệu hàng.

vẻ

Mã mới tôi đang cố gắng như thế này:

UPDATE @List 
    SET OrderNumBigInt = EXEC (ipCore.dbo.Getsequence 
            'ud_campaign_id', 
            @new_UD_campaignID OUTPUT) 

tôi không thể tìm thấy bất kỳ tài liệu hướng dẫn cụ thể cho biết bạn không thể thực hiện một thủ tục được lưu trữ trong một câu lệnh SELECT hoặc UPDATE để thiết lập một giá trị cột.

Có ai đã thử một cái gì đó tương tự, nhưng với sự thành công?

+0

Phiên bản SQL Server nào? – JNK

+1

Cũng có lý do bạn không thể tạo UDF cho proc thu được của mình để trả về giá trị? – JNK

+0

SQL Server 2008 R2 – JerryK

Trả lời

2

Điều bạn đang đề xuất không thể thực hiện trong MSSQL (AFAIK). Trong thực tế, tôi nghi ngờ các đề xuất để chuyển đổi GetSequence thành một hàm có lẽ sẽ không hoạt động hoặc là ud_campaing_id mới nhất có thể được lưu trữ trong một số bảng "toàn cục" ...

Giả sử các thủ tục lưu trữ GetSequence được gọi bởi các quá trình khác nhau "đồng thời", tôi muốn đề nghị bạn muốn một trong hai

  • cần phải thích ứng nói sp, do đó bạn có thể yêu cầu một loạt các mã cùng một lúc (thêm tham số, ví dụ: @number_of_ids mặc định là 1) để tham số đầu ra trả về id đầu tiên được yêu cầu nhưng nội bộ cũng dự trữ id tiếp theo cho bạn mà bạn có thể sử dụng để cập nhật @list
  • cần tạo vòng lặp chặt chẽ giúp bạn có được số id và sau đó áp dụng chúng trong một lần truy cập vào bảng mục tiêu của bạn.

Mặc dù tôi chắc chắn ủng hộ giải pháp cũ nhất, nó đòi hỏi phải thay đổi những gì có vẻ là một thủ tục được lưu trữ rất cốt lõi, điều mà dba có thể không thích hoặc cho phép. Tuy nhiên, nó sẽ làm cho mọi thứ nhanh hơn. Giải pháp thứ hai vẫn yêu cầu một số vòng lặp và cũng có một số yêu cầu lập chỉ mục nghiêm trọng khi áp dụng dữ liệu kết quả vào bảng kết thúc để nó hoàn hảo, nhưng có thể nhanh hơn một chút so với vòng lặp trực tiếp trên bảng mục tiêu và tìm nạp và áp dụng bản ghi dữ liệu mới theo bản ghi.

Đánh giá phương pháp UPDATE @list bạn đang sử dụng Tôi nghĩ bạn đã đi đúng hướng cho đề xuất thứ hai. Giả sử bạn có một lĩnh vực nhận dạng trong @list (với một hạn chế duy nhất hoặc PK vào nó và không có khoảng trống), bạn có thể thử một cái gì đó dọc theo những dòng:

DECLARE @RecordID, @LastRecordID int 
DECLARE @new_UD_campaignID bigint 

SELECT @RecordID = Min(RecordID), 
     @LastRecordID = Max(RecordID) 
    FROM @list 

DECLARE @newCampaingIDs TABLE (RecordID int PRIMARY KEY, new_UD_campaignID varchar(8)) 

WHILE @RecordID <= @LastRecordID 
    BEGIN 

     EXEC ppGlobal.dbo.Getsequence 'ud_campaign_id', @new_UD_campaignID OUTPUT 

     INSERT @newCampaingIDs (RecordID, new_UD_campaignID) VALUES (@RecordID, RIGHT('00000000' + CAST(@new_UD_campaignID AS VARCHAR(8)), 8)) 

     SELECT @RecordID = @RecordID + 1 
    END 

UPDATE @list 
    SET OrderNum = (CASE WHEN corpCamp LIKE '%LEP%' THEN 'L' ELSE 'C' END) + new_UD_campaignID 
    FROM @list upd 
    JOIN @newCampaingIDs new 
    ON new.RecordID = upd.RecordID 

Lý do tôi nghĩ này sẽ nhanh hơn là bởi vì các chèn liên tiếp sẽ có (rất nhiều?) ít chi phí hơn so với việc cập nhật bản ghi bảng gốc bằng bản ghi. Sau đó, một lần nữa, bạn vẫn bị mắc kẹt đằng sau việc gọi lại liên tục của proc GetSequence được lưu trữ mà có thể là người tiêu dùng thời gian chính của bạn.

Dù sao, cách duy nhất để biết chắc chắn là bằng cách kiểm tra nó =)

Chúc may mắn.

2

Đây là tài liệu - BNF cho UPDATEin BOL (trích) đọc

... 
UPDATE 
    ... 
    SET 
     { column_name = { expression | DEFAULT | NULL } 
    ... 

Định nghĩa cho expression phúc:

biểu

là một biến, giá trị văn chương, ngôn luận, hoặc một tuyên bố subselect (kèm theo dấu ngoặc đơn) rằng trả về một giá trị duy nhất. Giá trị được trả về bằng biểu thức sẽ thay thế giá trị hiện tại trong column_name hoặc @variable.

thực hiện SP là không có trong số này.

Bạn cần tìm cách khác để áp dụng logic - như JNK đề xuất trong một nhận xét, bạn có thể chuyển đổi logic SP thành một hàm để sử dụng nó trong bản cập nhật.

Ngoài ra, SP có thể được viết lại (hoặc SP mới được viết) để làm việc theo cách được thiết lập trên một nhóm hồ sơ không?

+0

Ông có thể sử dụng proc được lưu trữ để điền một bảng tạm thời và nhận các giá trị từ bảng tạm thời cho truy vấn của mình không? – JNK

+0

SP cập nhật bảng để chức năng không phải là một tùy chọn. Bởi vì SP trả về một giá trị vô hướng, một bảng tạm thời sẽ khá là vô ích. Tôi có thể phải quay trở lại với kiến ​​trúc sư và xem liệu tôi có thể thay đổi nó để có thể chấp nhận một tham số cho biết có bao nhiêu chuỗi tôi cần. Bảng SequenceNumbers được sử dụng để tránh trùng lặp số thứ tự, do đó, là loại quan trọng. – JerryK

+0

@JerryK - Tôi nghĩ rằng việc viết lại SP là lựa chọn duy nhất của bạn (hoặc xử lý nhiều hàng hoặc chia logic thành TVF để tính giá trị mới và cập nhật để lưu trữ chúng vào bảng). –

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