2011-02-08 26 views
12

Tôi đang cố gắng viết một thủ tục lưu sẵn để hỗ trợ phát triển cơ sở dữ liệu của chúng tôi, nhưng tôi đang gặp một số rắc rối khi sử dụng nó. Ví dụ:Sử dụng kết quả của biểu thức (ví dụ: Gọi hàm) trong danh sách tham số thủ tục lưu sẵn?

DECLARE @pID int; 
SET @pID = 1; 
EXEC WriteLog 'Component', 'Source', 'Could not find given id: ' + CAST(@pID AS varchar); 

này mang lại các lỗi (trên SQL Server 2005)

Msg 102, Level 15, State 1, Line 4 cú pháp sai gần '+'.

Ai đó có thể giải thích cho tôi tại sao cú pháp của tôi không chính xác và đúng cách để giải quyết vấn đề này?

Trả lời

18

Bạn cần sử dụng biến trung gian. SQL Server không hỗ trợ loại hoạt động này trong danh sách tham số chính nó mặc dù nó đã có trong danh sách TODO trong một vài năm! (Xem Connect Item: Use scalar functions as stored procedure parameters)

Các grammar for EXEC

[ { EXEC | EXECUTE } ] 
    { 
     [ @return_status = ] 
     { module_name [ ;number ] | @module_name_var } 
     [ [ @parameter = ] { value 
          | @variable [ OUTPUT ] 
          | [ DEFAULT ] 
          } 
     ] 
     [ ,...n ] 
     [ WITH <execute_option> [ ,...n ] ] 
    } 
[;] 

Các tài liệu không phải là hiện rằng rõ ràng về một định dạng có thể chấp nhận cho value nhưng nó có vẻ là chỉ "đơn giản" biểu như các giá trị văn chương hoặc @@ chức năng hệ thống tiền tố (chẳng hạn như @@IDENTITY). Không cho phép các chức năng hệ thống khác như SCOPE_IDENTITY() (ngay cả những chức năng không yêu cầu dấu ngoặc đơn như CURRENT_TIMESTAMP đều không được phép).

Vì vậy, trong thời gian này bạn cần phải sử dụng cú pháp như dưới đây

DECLARE @pID INT; 

SET @pID = 1; 

/*If 2008+ for previous versions this needs to be two separate statements*/ 
DECLARE @string VARCHAR(50) = 'Could not find given id: ' + CAST(@pID AS VARCHAR(11)) 

EXEC WriteLog 
    'Component', 
    'Source', 
    @string 
+3

Tôi đã hy vọng tránh các biến trung gian. Có cách nào thích hợp để làm điều này mà không giới thiệu chúng? – WorkerThread

+0

Ah, vừa xem giải thích của bạn. Cảm ơn bạn đã làm rõ điều này. – WorkerThread

+0

@Worker - Đó là tất cả một chút khó chịu. MS xác nhận nhiều ở đây https://connect.microsoft.com/SQLServer/feedback/details/352110/t-sql-use-scalar-functions-as-stored-procedure-parameters –

2
DECLARE @pID int; 
declare @IdAsString varchar(100) 

SET @pID = 1; 

Select @IdAsString ='Could not find given id: ' + Cast(@pId as varchar(10)) 

EXEC WriteLog 'Component', 'Source', @IdAsString 

Như đã chỉ ra bởi Martin, sau đây chỉ áp dụng cho các cột không biến.

Lưu ý rằng tôi đã sửa đổi dàn diễn viên của bạn để varchar(10) này sẽ cho phép số nguyên lớn hơn 1 chữ số. varchar sẽ chỉ cho phép 1 ký tự

+1

@Barry - Điều đó đúng với một cột nhưng mặc định cho biến 'varchar' là 10.' chọn CAST ('1234567890' là varchar) '. Bạn cần '11' cho toàn bộ dải' int' nếu bạn định cho phép phủ định. –

+0

@Martin - tôi cũng không biết điều đó. Cảm ơn bạn đã chỉ ra. Bạn có biết lý do tại sao các hành vi khác nhau? – codingbadger

+0

@Barry - Không - có vẻ như một sự mâu thuẫn không ổn định. Tôi đoán có lẽ một số lý do lịch sử ... –

1

Bạn không thể thực hiện các tham số của quy trình được lưu trữ. Bạn nên gán giá trị đó vào một biến khác và sau đó chuyển nó vào SP của bạn.

DECLARE @pID int, @nameId VARCHAR(100); 
SET @pID = 1; 
SET @nameId = 'Could not find given id: ' + CAST(@pID AS varchar); 

EXEC WriteLog 'Component', 'Source', @nameId 
0

Có lẽ một cái gì đó như thế này?

DECLARE @pID int; 
SET @pID = 1; 

DECLARE @Message NVARCHAR(50); 

SET @Message = 'Could not find given id: ' + CAST(@pID AS varchar) 
EXEC WriteLog 'Component', 'Source', @Message; 
0

Hãy thử điều này thay vì ...

DECLARE @pID int; 
SET @pID = 1; 

DECLARE @message varchar(255); 
SET @message = 'Could not find given id: ' + CAST(@pID AS varchar) 

EXEC WriteLog 'Component', 'Source', @message; 
0

DECLARE @ id int

SET @ id = 10

CHỌN LTRIM (RTRIM (STR (@ id))) AS stringValue

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