227 votes

est d'un type non valide pour une utilisation en tant que colonne de clé dans un index

J'ai une erreur à

 Column 'key' in table 'misc_info' is of a type that is invalid for use as a key column in an index.
 

où clé est un nvarchar (max). Un rapide Google a trouvé ceci . Cependant, cela n'explique pas ce qu'est une solution. Comment puis-je créer quelque chose comme Dictionnaire où la clé et la valeur sont les deux chaînes et évidemment la clé doit être unique et est unique. Ma déclaration SQL était

 create table [misc_info] (
[id] INTEGER PRIMARY KEY IDENTITY NOT NULL,
[key] nvarchar(max) UNIQUE NOT NULL,
[value] nvarchar(max) NOT NULL);
 

289voto

Daniel Renshaw Points 12272

Une contrainte unique ne peut pas dépasser 8 000 octets par ligne et n'utilise que les 900 premiers octets, même si la taille maximale la plus sûre pour vos clés est la suivante:

 create table [misc_info]
( 
    [id] INTEGER PRIMARY KEY IDENTITY NOT NULL, 
    [key] nvarchar(450) UNIQUE NOT NULL, 
    [value] nvarchar(max) NOT NULL
)
 

c'est-à-dire que la clé ne peut pas contenir plus de 450 caractères. Si peut passer à varchar au lieu de nvarchar (par exemple, si vous n'avez pas besoin de stocker des caractères provenant de plus d'une page de code), le nombre de caractères peut atteindre 900.

35voto

Marwan Points 480

Il y a une limitation dans SQL Server (jusqu'en 2008 R2) varchar(MAX) et de type nvarchar(MAX) (et plusieurs autres types comme text, ntext ) ne peut pas être utilisé dans des indices. Vous avez 2 options:
1. Définir une taille limitée, sur le champ de clé ex. nvarchar(100)
2. Créer une contrainte de validation qui permet de comparer la valeur avec les touches du tableau. La condition est:

([dbo].[CheckKey]([key])=(1))

et [dbo].[CheckKey] est une fonction scalaire définie comme:

CREATE FUNCTION [dbo].[CheckKey]
(
    @key nvarchar(max)
)
RETURNS bit
AS
BEGIN
    declare @res bit
    if exists(select * from key_value where [key] = @key)
        set @res = 0
    else
        set @res = 1

    return @res
END

Mais notez qu'un natif de l'indice est plus performant qu'une contrainte check donc, à moins que vous vraiment ne pouvez pas spécifier la longueur, ne pas utiliser la vérification de la contrainte.

17voto

Don Points 3351

La seule solution consiste à utiliser moins de données dans votre index unique. Votre clé peut être NVARCHAR (450) au maximum.

"SQL Server conserve la limite de 900 octets pour la taille totale maximale de toutes les colonnes de clé d'index."

En savoir plus sur MSDN

11voto

Une solution serait de déclarer votre clé comme nvarchar(20) .

2voto

Neil Moss Points 3581

Notant klaisbyskov du commentaire à propos de la longueur de votre clé avoir besoin de plusieurs gigaoctets, et en supposant que vous n'avez en fait besoin de cela, alors je pense que vos seules options sont les suivantes:

  1. utiliser une table de hachage de la valeur de la clé
    • Créer une colonne sur nchar(40) (pour un hash sha1, par exemple),
    • mettre une clé unique sur la valeur de hachage de la colonne.
    • générer le hachage lors de l'enregistrement ou de la mise à jour de l'enregistrement
  2. les déclencheurs pour interroger la table pour un match lors de l'insertion ou de mise à jour.

Le hachage est livré avec la mise en garde qu'un jour, vous pourriez obtenir une collision.

Les déclencheurs va scanner l'ensemble de la table.

De plus pour vous...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X