2013-01-03 94 views
27

Dưới đây là mã của tôi:Stored Procedure giá trị tham số mặc định - là này một hằng số hoặc một biến

USE [xxx] 
GO 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

CREATE PROCEDURE [dbo].[problemParam] 
    @StartDate INT = CONVERT(INT,(CONVERT(CHAR(8),GETDATE()-130,112))), 
    @EndDate INT = NULL 
AS 
BEGIN 

SSMS là không quá hài lòng với mặc định giá trị tôi đã sử dụng - trong MSDN DEFINITION HERE nó nói rằng giá trị mặc định cần phải là một hằng số thay vì một biến.

Có phải là CONVERT(INT,(CONVERT(CHAR(8),GETDATE()-130,112))) biến hoặc hằng số không? Nó không phải là một biến trong cách truyền thống tôi nghĩ về một biến nhưng sau đó một lần nữa nó không phải là một hằng số như '03 jan 2013' là.

Làm cách nào để giải quyết vấn đề này? Di chuyển CONVERT(INT,(CONVERT(CHAR(8),GETDATE()-130,112))) đến ứng dụng khách đang gọi thủ tục được lưu trữ?


EDIT

có thể trùng lặp như tôi vừa phát hiện này SO POST

+0

Kết quả của 'GETDATE()' * thay đổi * theo thời gian sao cho nó không thể không đổi. Sử dụng NULL/một giá trị ma thuật cho một mặc định, phát hiện nó và gán biểu thức của bạn nên nó phù hợp. –

+0

@AlexK. Tôi không chắc chắn nếu bạn là chính xác: chắc chắn 'GETDATE()' được đánh giá khi nó được gọi và sau đó không đổi. Xem [** các bài đăng trên blog này **] (http://sqlblog.com/blogs/andrew_kelly/archive/2008/03/01/when-a-function-is-indeed-a-constant.aspx) - xem có thể gây tranh cãi – whytheq

Trả lời

36

Nó có phải là một liên tục - giá trị phải được tính toán tại thời điểm mà các thủ tục là tạo ra, và rằng một tính toán phải cung cấp giá trị sẽ luôn được sử dụng.

Nhìn vào định nghĩa của sys.all_parameters:

default_valuesql_variant Nếu has_default_value là 1, giá trị của cột này là giá trị mặc định cho tham số; nếu không, NULL.

Tức là, bất kể thông số mặc định cho tham số là gì, nó phải phù hợp với cột đó.


Như Alex K chỉ ra trong các ý kiến, bạn chỉ có thể làm:

CREATE PROCEDURE [dbo].[problemParam] 
    @StartDate INT = NULL, 
    @EndDate INT = NULL 
AS 
BEGIN 
    SET @StartDate = COALESCE(@StartDate,CONVERT(INT,(CONVERT(CHAR(8),GETDATE()-130,112)))) 

với điều kiện NULL không có ý định trở thành một giá trị hợp lệ cho @StartDate.


Đối với các bài viết trên blog bạn liên kết với trong các ý kiến ​​- đó là nói về một bối cảnh rất cụ thể - đó, kết quả đánh giá GETDATE() trong bối cảnh của một đơn truy vấn thường được coi là không thay đổi. Tôi không biết nhiều người (không giống như tác giả blog), người sẽ xem xét một biểu thức riêng bên trong UDF là một phần của cùng một truy vấn với truy vấn gọi số UDF.

+0

+1 cho giải pháp này.Đó chắc chắn là một sự khác biệt tinh tế nếu tôi thay đổi 'phải được tính toán tại thời điểm thủ tục được tạo ra,' đến 'phải được tính toán tại thời điểm thủ tục được thực thi, 'sau đó đến khi sproc có liên quan' GETTIME () 'sẽ là một _constant_. Giống như việc sử dụng 'COALESCE' tôi đã sử dụng' IF @StartDate IS NULL ... ' – whytheq

+0

@whytheq - nếu nó chỉ phải được tính toán tại thời điểm thủ tục được thực thi, cái gì * sẽ không * được cho phép tại thời điểm đó ? –

+0

... nếu cần 2 phút để thực thi và tôi đặt '@ StartDate' thành biến truyền thống nói' @StartDate INT = @ x' sau đó ban đầu đặt @x thành '01 jan 2013 'và sau đó trong proc thay đổi nó thành '02 jan 2013 'sau đó tôi muốn nói rằng chắc chắn là một biến và không phải là một hằng số; tách tóc một chút. – whytheq

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