Avant de publier un élément de connexion concernant le manque de documentation à ce sujet, quelqu'un confirmera-t-il que je ne manque pas simplement quelque chose ici?
Sur la page de documents où format
est répertoriée en tant que fonction de chaîne:
"Toutes les fonctions de chaîne intégrées sont déterministes." - Fonctions de chaîne (Transact-SQL)
Il n'y a également aucune mention d' format
être non déterministe sur les pages connexes:
Cependant, lorsque vous tentez de créer une colonne calculée persistante:
create table t (date_col date);
insert into t values (getdate());
alter table t add date_formatted_01 as format(date_col,'YYYY') persisted;
Renvoie l'erreur suivante:
La colonne calculée 'date_formatted_01' dans la table 't' ne peut pas être conservée car la colonne n'est pas déterministe.
La documentation indique que
Si l'argument culture n'est pas fourni, la langue de la session en cours est utilisée.
mais l'ajout d'un argument de culture ne change rien
Cela échoue également
alter table t add date_formatted_02 as format(date_col, 'd', 'en-US' ) persisted
démo rextester: http://rextester.com/ZMS22966
Démo dbfiddle.uk: http://dbfiddle.uk/?rdbms=sqlserver_next&fiddle=7fc57d1916e901cb561b551af144aed6
la source
alter table #t add date_formatted_01 as CONVERT(VARCHAR(20), FORMAT(date_col, 'YYYY', 'en-US')) persisted;
. Je ne sais pas pourquoiFORMAT
n'est pas déterministe, surtout quand on spécifie la culture. Ladate_formatted
colonne peut êtreVARCHAR(20)
(toujours persistante) et définie via Trigger à l'aide deFORMAT
. Ou SQLCLR fonctionne. En utilisant la bibliothèque SQL # SQLCLR (que j'ai écrite), vous pouvez le faireALTER TABLE SQL#.t ADD date_formatted_03 AS SQL#.Date_Format(date_col, 'd', 'en-US') PERSISTED;
(la table appartient à SQL # car le propriétaire de la table et de la fonction doit être le même).Réponses:
Une fonction n'est pas nécessairement déterministe ou non déterministe. Certaines fonctions peuvent être déterministes en fonction de leur utilisation :
CAST
etCONVERT
sont de tels exemples. Sur la base des tests que vous avez effectués jusqu'à présent, je pense qu'il est juste de dire que ceFORMAT
n'est pas toujours déterministe, bien qu'il s'agisse d'une fonction de chaîne. Si vous voulez savoir si c'est parfois déterministe, la seule technique à laquelle je peux penser est d'essayer suffisamment de façons différentes de l'appeler jusqu'à ce que vous soyez satisfait. Par exemple, considéronsFORMAT
comme appliqué aux nombres. Il n'y a que dix types d'entrées numériques différents :Il semble également qu'il n'y ait que neuf formats numériques différents . Il est possible d'essayer de créer des colonnes persistantes pour toutes les combinaisons possibles. Un code pour le faire est ci-dessous:
Voici un échantillon de la sortie:
Je n'ai pu obtenir aucune des colonnes à ajouter au tableau pour quelques valeurs d'entrée et cultures. Je n'ai pas essayé de façon exhaustive toutes les cultures possibles car je ne trouve pas de liste d'entre elles dans SQL Server.
Au minimum, il semble sûr de conclure que la documentation concernant le déterminisme de
FORMAT
est incorrecte, donc je recommanderais de lui soumettre un élément de connexion.la source
La
FORMAT
documentation a maintenant été mise à jour (en réponse à votre élément Connect ) pour indiquer:De même, les fonctions de chaîne (Transact-SQL) incluent désormais:
la source
Je ne suis pas un utilisateur régulier de sqlserver, donc je peux me tromper, mais je suppose que le format n'est pas une fonction de chaîne. Selon la documentation:
https://docs.microsoft.com/en-us/sql/t-sql/functions/format-transact-sql
format prend soit un type de date soit un type numérique comme argument. Si tout ce que vous voulez faire est de saisir la partie année d'une date, ne pouvez-vous pas utiliser la fonction année?
si vous voulez une représentation sous forme de chaîne:
la source