2008-10-29 10 views
5

Ich habe eine XML-Spalte in einer Tabelle; Ich möchte einen bestimmten Wert in diesem XML als berechnete Spalte "hochstufen" und für schnellere Suche indizieren. Ich habe eine Funktion, die in der XML-Informationen nimmt und gibt das Element von Interesse, wie folgt aus:Persistent einer berechneten Datetime-Spalte in SQL Server 2005

CREATE FUNCTION [dbo].[fComputeValue] (@data XML) 
RETURNS datetime 
WITH SCHEMABINDING 
AS 
BEGIN 
    RETURN @data.value('(/Metadata/Value[@Key="StartDate"])[1]', 'datetime') 
END 

Allerdings, wenn ich versuche, die berechnete Spalte zu erstellen:

ALTER TABLE dbo.CustomMetadataTable ADD [StartDate] AS ([dbo].[fComputeValue]([CustomMetadataColumn])) PERSISTED 

ich die folgende Fehlermeldung erhalten:

Msg 4936, Level 16, State 1, Line 2 Computed column 'StartDate' in table 'CustomMetadataTable' cannot be persisted because the column is non-deterministic.

Es funktioniert, wenn ich:

  • arbeiten mit varchar, int, double (d. H. andere als Datetime) Werte
  • das PERSISTED Stichwort entfernen (aber dann kann ich nicht einen Index für die Spalte)

Ich mag auch, dass die Datums- und Uhrzeitwerte erwähnen sind in XSD Datetime-Format erstellen. Irgendwelche Ideen? Vielen Dank.

Antwort

6

Was:

CREATE FUNCTION [dbo].[fComputeValue] (@data XML) 
RETURNS varchar(50) 
WITH SCHEMABINDING 
AS 
BEGIN 
    RETURN @data.value('(/Metadata/Value[@Key="StartDate"])[1]', 'varchar(50)') 
END 

und:

ALTER TABLE dbo.CustomMetadataTable ADD [StartDate] AS (convert(datetime,([dbo].[fComputeValue]([CustomMetadataColumn]), 127)) PERSISTED 

oder:

return convert(datetime, @data.value('(/Metadata/Value[@Key="StartDate"])[1]', 'varchar(50)'), 127) 

Von Bücher online:

CONVERT is Deterministic unless one of these conditions exists:

Source type is sql_variant.

Target type is sql_variant and its source type is nondeterministic.

Source or target type is datetime or smalldatetime, the other source or target type is a character string, and a nondeterministic style is specified. To be deterministic, the style parameter must be a constant. Additionally, styles less than or equal to 100 are nondeterministic, except for styles 20 and 21. Styles greater than 100 are deterministic, except for styles 106, 107, 109 and 113.

Es könnte helfen, wenn Sie CONVERT mit Stil verwenden 127

+0

Vielen Dank! Ich hatte das gleiche Problem. Ich frage mich, warum 127 funktioniert, wenn andere es nicht tun? – harpo

+0

Dies ist der Grund: "Stile größer als 100 sind deterministisch, außer für die Stile 106, 107, 109 und 113." –

+0

Anstatt die ALTER TABLE-Anweisung zu ändern, können Sie auch die fComputeValue-FUNCTION-Definition ändern: Die Funktion kann datetime zurückgeben, wie das OP es wollte, wenn Sie CONVERT mit Stil 127 im body/implementation der Funktion aufrufen. – ChrisW