2008-10-29 7 views
5

J'ai une colonne XML dans une table; Je veux "promouvoir" une certaine valeur dans ce XML en tant que colonne calculée et l'indexer pour une recherche plus rapide. J'ai une fonction qui prend les informations XML et fournit l'élément d'intérêt, comme celui-ci:Persistance d'une colonne datetime calculée dans 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 

Cependant, lorsque je tente de créer la colonne calculée:

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

Je reçois l'erreur suivante:

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

Il fonctionne si je:

  • fonctionne avec varchar, int, double (c.-à-d. autre que datetime) valeurs
  • supprimer le mot-clé PERSISTED (mais je ne peux pas créer un index sur la colonne)

Je dois aussi mentionner que les valeurs datetime sont en XSD le format datetime. Des idées? Merci.

Répondre

6

Qu'en est-:

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

et:

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

ou:

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

Des livres en ligne:

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.

Il pourrait être utile si vous utilisez CONVERT avec le style 127

+0

Merci! J'ai eu le même problème. Je me demande pourquoi 127 fonctionne quand les autres ne le font pas? – harpo

+0

C'est la raison: "Les styles supérieurs à 100 sont déterministes, sauf pour les styles 106, 107, 109 et 113." –

+0

Au lieu de modifier l'instruction ALTER TABLE, vous pouvez également modifier la définition fComputeValue FUNCTION: la fonction peut renvoyer datetime comme l'OP le souhaitait, si vous invoquez CONVERT avec le style 127 dans le corps/implémentation de la fonction. – ChrisW

Questions connexes