2013-01-03 7 views
27

Tu jest mój kodu:procedury przechowywanej Domyślna wartość parametru - jest to stała lub zmienna

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 nie jest zbyt zadowolony z domyślny wartości używałem - w MSDN DEFINITION HERE mówi, że wartość domyślna musi być stała, a nie zmienna.

Czy CONVERT(INT,(CONVERT(CHAR(8),GETDATE()-130,112))) jest zmienną czy stałą? Nie jest to zmienna w tradycyjny sposób, jak myślę o zmiennej, ale potem znowu nie jest stała jak jest '03 jan 2013'.

Jak sobie z tym poradzić? Przenieść CONVERT(INT,(CONVERT(CHAR(8),GETDATE()-130,112))) do klienta, który wywołuje procedurę przechowywaną?


EDIT

Możliwy duplikat jako Właśnie nanosi ten SO POST

+0

Wynik 'GETDATE()' * zmienia się * według czasu, więc nie może być stały. Użyj wartości NULL/magicznej dla wartości domyślnej, wykryj ją i przypisz swoje wyrażenie, jeśli jest zgodne. –

+0

@AlexK. Nie jestem pewien, czy masz rację: na pewno 'GETDATE()' jest oceniany, gdy jest wywoływana, a następnie stała. Zobacz [** te posty na blogu **] (http://sqlblog.com/blogs/andrew_kelly/archive/2008/03/01/when-a-function-is-indeed-a-constant.aspx) - widzi być dyskusyjnym – whytheq

Odpowiedz

36

To musi być stała - wartość musi być obliczalna w czasie, że procedura jest utworzone i to jedno obliczenie musi dostarczyć wartość, która będzie zawsze używana.

Spójrz na definicji sys.all_parameters:

default_valuesql_variant Jeśli has_default_value wynosi 1, wartość tej kolumnie jest wartość domyślna dla parametru; w przeciwnym razie, NULL.

Oznacza to, że niezależnie od wartości domyślnej parametru, musi on pasować do tej kolumny.


Alex K zauważył w komentarzach, można po prostu zrobić:

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

pod warunkiem, że NULL nie ma być prawidłową wartością @StartDate.


Co do blogu jesteś powiązany w komentarzach - który mówi o bardzo specyficznym kontekście - tym, wynik oceniania GETDATE() w kontekście pojedynczego zapytania jest często uważana za stały. Nie znam wielu ludzi (w przeciwieństwie do autora bloga), którzy rozważaliby oddzielne wyrażenie wewnątrz UDF, aby być częścią tego samego zapytania, co zapytanie, które wywołuje UDF.

+0

+1 dla tego rozwiązania.Jest to z pewnością subtelna różnica, jeśli zmienię "musi być obliczalne w czasie, gdy procedura jest tworzona," na "musi być obliczalne w czasie wykonywania procedury, a następnie, jeśli chodzi o sproc), GETTIME () 'byłby _konstentem_. Podobnie jak w przypadku użycia 'COALESCE' użyłem' IF @StartDate IS NULL ... ' – whytheq

+0

@whytheq - jeśli musiało być obliczalne tylko w momencie wykonania procedury, co * nie * byłoby dozwolone w tym czasie ? –

+0

... jeśli zajmie 2 minuty, a ja ustawię '@ StartDate' na tradycyjną zmienną, powiedz' @StartDate INT = @ x', a następnie ustaw na początek @x na '01 jan 2013 ', a później w proc, zmień ją na "02 stycznia 2013 r.", Powiedziałbym, że jest to niewątpliwie zmienna, a nie stała; trochę rozłupuje włosy. – whytheq

Powiązane problemy