2008-10-29 21 views
5

Tengo una columna XML en una tabla; Quiero "promover" un cierto valor en ese XML como una columna calculada e indexarlo para una búsqueda más rápida. Tengo una función que toma en la información de XML y da salida al elemento de interés, como esto:Persistencia de una columna de fecha y hora calculada en 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 

Sin embargo, cuando intento crear la columna calculada:

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

me sale el siguiente error:

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

funciona si:

  • trabajo con varchar, int, double (es decir que no sea de fecha y hora) Valores
  • quitar la palabra clave PERSISTED (pero entonces no puedo crear un índice en la columna)

También debería mencionar que los valores de fecha y hora están en formato de fecha y hora XSD. Alguna idea? Gracias.

Respuesta

6

¿Qué hay de:

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

y:

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

o:

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

De los libros en línea:

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.

Podría serle útil si usa CONVERT con estilo 127

+0

¡Gracias! Yo tuve el mismo problema. Me pregunto por qué 127 funciona cuando otros no? – harpo

+0

Esta es la razón: "Los estilos superiores a 100 son determinísticos, excepto los estilos 106, 107, 109 y 113". –

+0

En lugar de cambiar la instrucción ALTER TABLE, también puede cambiar la definición de función fComputeValue FUNCTION: la función puede devolver datetime como lo deseó OP, si invoca CONVERT con el estilo 127 en el cuerpo/implementación de la función. – ChrisW

Cuestiones relacionadas