erreur clef trop grande ! [SQL server 2005] - SQL/NoSQL - Programmation
Marsh Posté le 14-06-2007 à 13:09:34
tu as des tables liees ?
Marsh Posté le 14-06-2007 à 13:20:48
Crée une nouvelle table et copie les colonnes non-identity dedans. Il regénérera une colonne id correcte. Puis tu droppes la mauvaise table et tu renommes la nouvelle avec le bon nom.
Je pense que ça devrait marcher.
Marsh Posté le 14-06-2007 à 13:23:26
Oui j'ai beaucoup de table lié à celle-si et surtout elle sont lié sur ce champ !
Je peu pas faire comme tu dit bignose je pense qu'il va me perdre tout les liens entre les données(des autres tables liées) et ID si je fais comme tu dit ...
Marsh Posté le 14-06-2007 à 13:31:32
Je viens de rééssayer avec l'ancien base access, le champ ID et donc bien en mode Numéroauto et ca marche .
Access est assez intélligent pour trouver une valeur de clé primaire non continue au milieu de l'int alors que SQL server plante !!! Ca craint!
Marsh Posté le 14-06-2007 à 13:35:53
Si tes tables sont liées uniquement via les valeurs des ids et pas via des foreign keys ou des contraintes, tu peux utiliser une table intermédiaire qui reprend l'ancienne valeur de l'id et la nouvelle et faire un update des autres tables à partir d'elle.
Conseil, mais probablement inutile, fais un backup de ta db avant ce genre de manipulation...
Marsh Posté le 14-06-2007 à 13:38:26
Access et SQL Server c'est pas le mème usage ni les mèmes capacités ou performances. Bref c'est pas comparable. Access fera jamais mieux que SQL server.
Marsh Posté le 14-06-2007 à 13:39:11
Si, les autres tables sont liée via une foreign key à ce champ merdique
Marsh Posté le 14-06-2007 à 13:40:37
Rhaaaaa!!!!
Pas de chance.
Tu peux pas scripter la création des contraintes, les dropper puis corriger tes tables et recréer les contraintes avec les scripts après ?
Marsh Posté le 14-06-2007 à 13:44:37
oula, là j'ai po capté
Scripter la créatin des contraintes ca veut dire quoi ?? je suis sur Win serv 2003.
dropper et corriger quel table ??
et recréer quel contrainte ?
lol je suis à l'ouest là
Mais sinon ya pas moyen que SQL server 2005 réfléchissent un peu pour trouver des ID pas séquentiel ?
Marsh Posté le 14-06-2007 à 14:03:25
J'ai essayé en créant une table avec les même champs et en copiant juste les données et pas la clé primaire ca corrompt bien toutes les données comme pévu
Help help help je sais vraiment pas comment faire
Marsh Posté le 14-06-2007 à 15:19:03
TILT voici peut etre une solution si vous pouviez me dire ce que vous en pensez avant que je fasse tout planter :
1°) Création d'un nouveau champ ID_nouv de type identity et étant cle primaire (si ca marche pas d'un coup je passerai en créant une autre table et en copiant les données)
2°) Mettre les Foreign Key qui sont sur le champ ID de base vers le nouveau champ ID_nouv
3°) Virer le champ Id de base
4°) Rennomer le nouveau champ ID_nouv en ID de base
Ca peut marcher cette combine ?
Marsh Posté le 14-06-2007 à 15:28:29
Dropper et corriger la table dont les IDs sont faux. Celle qui te pose problème.
Tu m'as dit qu'il y avait des contraintes d'intégrité. Et des foreign keys définies sur les tables. Tu dois les voir dans studio management.
Dans studio management, tu peux faire un clic droit sur la table et choisir script table as "Create ...". Dans ce script tu dois juste conserver la création des constrains, pas la création de la table qui existe déja. Une fois que t'as les scripts pour toutes les tables, tu peux deleter les contraintes. Plus tard tu pourras les recréer avec ces scripts.
Maintenant ya peut ètre plus simple. Je sais pas. C'est une piste à explorer.
SQL Server fait ce qu'on lui dit. Une colonne de type Identity est ce qu'elle est. Si tu veux pouvoir assigner n'importe quelle valeur faut mettre du int ou du bigint. Ya pas de secret. Si Access fait des chippotages, c'est son problème. C'est pas pour rien qu'on l'utilise pas ou peu dans des environnements de prod. Et ceux qui le font c'est à leurs risques et périls.
Marsh Posté le 14-06-2007 à 15:34:09
ouai mais access en attendant il est intelligent, son autoincrément trouve des numéros au milieu. Alors que SQL server essaye de rajouter juste a la fin et cherche pas plus loin si la table est completement pleine ...
Le scipt à lancer je dois le faire sur toute les tables ou ce champ est en foreign key ? je vois pas trop ce que ca va faire et a quoi ca va servir. Si je delete les contraintes ca changera pas mon problème non . Si aprés je delete le champ ID et que je le remplace par un autre que j'aurai créé ca va merder pareil non ?
Le script de contrainte crée ces contraintes pour chaque enregistrement de chaque table vers chaque enregistrement de la table ou il y a l'ID qui merde ?
merci
Marsh Posté le 14-06-2007 à 15:40:58
En fait il me faudrai un utilitaire qui me change dans toute les tables ou il y a des Foreign key, l'ID courant (celui où il y a plein de trou) par un nouvelle ID que j'aurai créé a coté et qui sera lui continue a partir de 0.
Mais SQL server peut le faire ca ? quand je vais changer la Foreign key il va me demander de mettre a jour les champs où il va change la clé sans modifier les données ce qui me cassera toute mon intégrité de mes données ?
Marsh Posté le 14-06-2007 à 15:42:57
L'idée c'est:
- crée les scripts pour les contraintes. Tu peux tout regrouper dans un seul script, c'est du copy/paste.
- crée une nouvelle table ou tu copies celle qui pose problème.
- crée une deuxième table qui fait le lien entre les anciens ids et les nouveaux.
- droppe les contraintes.
- droppe la table problématique.
- renomme la table correcte avec le bon nom.
- corrige les ids des tables via un update avec la table faisant le lien.
- exécute les scripts (ou le script si t'a tout regroupé dans un seul) pour recréer les contraintes.
Encore une fois c'est une piste, ya peut ètre plus simple. Une ame charitable donnera peut ètre une autre idée.
Pour ce qui est de ton idée à mon avis tu vas avoir des problèmes avec les contraintes... Et c'est du manuel. Mais ça coute rien d'essayer tant que t'as un backup de ta db.
Marsh Posté le 14-06-2007 à 15:53:14
Ok c'était un peu dans mon idée
Les scipts créé en fait ils disent juste, liéer le champ X de la table toto au champ ID de la table qui merde. C'est bien ca ?
La table correct c'est celle qui aura les nouveau bon ID à la place des merdiques ?
La requete update pour corriger les ID des tables je vois pas trop comment la faire ... désolé.
Il faut le faire récursivement pour tout les enregistrements en plus ?
tu aurai un exemple stp
Genre pour la table toto(celle où il y a la FK qui point sur la table merdique), avec la table lien qui s'appelle lien_FK et la bonne table corrigé table_OK.
merci de ton aide
Marsh Posté le 14-06-2007 à 16:10:13
Si je fais une requete SQL comme ca :
UPDATE toto
SET SOC_ID = ( SELECT nouv_SOC_ID FROM lien_FK)
WHERE lien_FK.Ancien_SOC_ID = toto.SOC_ID
Ca marche ?
Marsh Posté le 14-06-2007 à 16:13:27
ou plutot ca :
UPDATE toto
SET SOC_ID = ( SELECT nouv_SOC_ID
FROM lien_FK WHERE lien_FK.Ancien_SOC_ID = toto.SOC_ID)
WHERE lien_FK.Ancien_SOC_ID = toto.SOC_ID
???
Faut-il que je lie les tables toto et lien_FK ?
Marsh Posté le 14-06-2007 à 17:33:06
"identity", c'est pas un type... c'est juste un flag.
par contre, "integer", C'EST UN TYPE DE MERDE QUI N'EST PAS FAIT POUR FAIRE DES CLES PRIMAIRES BORDEL DE MERDE CA FAIT 4 ANS QUE JE ME FAIT CHIER A PRECHER DANS LE DESERT CA DEVIENT GONFLANT !
Change ton champ ID en NUMERIC bordel
Marsh Posté le 14-06-2007 à 17:34:58
Et un numeric il va de 0 a 2^32 ?
Si j'ai des clé négative déjà existante ca va donner quoi ?
(la base n'a pas été créé par moi mais par un autre petit stagiaire qui a oublié plein de clé primaire aussi )
Marsh Posté le 14-06-2007 à 17:36:30
Non, un numéric ça a 40 chiffres de précision, quelque soit le nombre de décimales. Et 40 chiffres de précision, c'est >>> 2^32
PS : Y'a pas autant d'atomes qui forment la Lune.
Marsh Posté le 14-06-2007 à 22:03:40
Oki,
Et access prendra en compte ce type numeric ?
Je ne pense pas et SURTOUT le type numerique access ne va pas jusqua plus de 2^32 et c'est ce qu'il me faut si tu as bien lu mon poste.
Je pense pas que le type numérique fasse du 2^40 ... ni sous SQL server et encore moin sous Access. Mais bon peut etre que je me trompe et ca serai cool pour moi
Quelqu'un peut me dire si mes requete SQL que j'ai écrite plus haut sont bonne svp, enfin si l'une des 2 l'est
Marsh Posté le 15-06-2007 à 09:52:02
MagicBuzz a écrit : "identity", c'est pas un type... c'est juste un flag. |
pourquoi on pourraist pas utiliser int pour une clé primaire ?
Marsh Posté le 15-06-2007 à 10:02:49
thekingsky > en effet, après tests, Access ne semble pas être cable de gérer ce type (t'ain mais c'est trop de la merde Access en fait )
the prosoner > simplement pour une chiée de raisons.
1/ un ID, c'est une information interne, pas une valeur sur laquelle on fait des calculs. on se moque donc de la représentation interne du nombre (à noter que number est une véritable merde à gérer pour faire des calculs)
2/ un ID, c'est indexé. de nouveau, quelque soit le type utilisé, les performances seront les mêmes pour le relire, puisqu'on passera toujours par l'index
3/ ça évite les problèmes "ah ben merde, j'ai plus de 4 millions d'enrestrement dans ma table, ça fait boum, je sais plus quoi faire "
4/ parceque c'est comme ça
A noter que "number" doit aussi être utilisé IMPERATIVEMENT pour tout ce qui est gestion de prix, taxes, etc. Effectivement float a une précision de merde, qui peut provoquer des erreurs d'arrondis, et c'est chiant de remettre en cause un travail de 3 ans de dev pour 2 centimes d'écarts qui empêchent la validation comptable
Marsh Posté le 15-06-2007 à 10:10:45
Merci magicBuzz mais ca me dit po comment faire
La solution de bignose à l'air cool mais je sais pas si mes requete update vont bien faire ce que j'aimerais qu'elle fasse ...
Marsh Posté le 15-06-2007 à 10:13:43
MagicBuzz a écrit : |
J'utilise plutot decimal pour les flottant.
Marsh Posté le 15-06-2007 à 10:32:06
thekingsky a écrit : Merci magicBuzz mais ca me dit po comment faire |
Alter tes FK pour que "on update" ça "cascade".
Ensuite, t'as juste à remplacer les valeurs de tes ID foireux en mettant un nombre de 1 à 4000 et quelques.
Ca se fait en 30 secondes avec Excel :
select id from latablefoireuse;
=> copier commer dans la colonne "D" d'une feuille excel.
Dans la première ligne de la colonne "A" :
"update matablefoireuse set id ="
Dans la colonne "B" :
1
Dans la colonne "C" :
"where id = "
Dans la colonne "E" :
=concatenate(A1,B1,C1,D1)
Sur la colonne C, click click sur le petit carré en bas à droite de la la cellule : miracle, ça copie "where id =" sur toutes les lignes jusqu'à la dernière valeur de D
Idem sur B : Miracle, ça fait 1, 2, 3, ... tout pareil !
Idem A
Et enfin E
Sélection colonne E ctrl + C
CTRL + V dans SQL Query Analyzer
F5
Marsh Posté le 15-06-2007 à 10:52:05
Dans le géstionnaire de sql server dans mes table connécté je double clic sur la FK et ya un champ sur INTERT et UPDATE que je déplie
et là il y a pour UPDATE une liste déroulante avec cascade dedant. Je met ca pour chaque table où il y à cette FK
Marsh Posté le 15-06-2007 à 10:55:24
Et il faut aussi que l'update ce fasse dans le même sens que le select du départ !
edit : => question débile
Par contre pour le update en cascade c po pareil
Marsh Posté le 15-06-2007 à 11:11:46
D'ailleur c'est pas plutot la clé primaire de la table qui merde qu'il faut mettre en Update en cascade ?
Marsh Posté le 15-06-2007 à 11:13:11
thekingsky a écrit : Dans le géstionnaire de sql server dans mes table connécté je double clic sur la FK et ya un champ sur INTERT et UPDATE que je déplie |
tu mets ça partout où il y a une FK qui pointe sur ce champ.
Marsh Posté le 15-06-2007 à 11:14:14
c'te bordel, je pige rien à ton truc.
je te colle un exemple.
Marsh Posté le 15-06-2007 à 11:47:07
Ton bordel actuel, si j'ai bien compris :
Code :
|
Ce qui donne :
|
Premier truc : vire le "identity" pour le moment, c'est pas updateable donc t'es comme un con.
Ensuite, donc, la FK "fk_merdageexpress" doit être modifée pour se mettre à jour en cascade.
Code :
|
Et maintenant, tu peux modifier tes valeurs d'id :
Code :
|
Ce qui donne :
|
Marsh Posté le 15-06-2007 à 12:03:54
MagicBuzz a écrit : thekingsky > en effet, après tests, Access ne semble pas être cable de gérer ce type (t'ain mais c'est trop de la merde Access en fait ) |
ouais donc finalement, seulement utile lorsqu'on prevoit des millions de records.
Marsh Posté le 15-06-2007 à 12:23:41
the prisoner a écrit : ouais donc finalement, seulement utile lorsqu'on prevoit des millions de records. |
non, tu prévoies rien du tout.
aujourd'hui ton analyse dit que tu vas avoir 3 lignes dans une table. rien ne te dis que demain ça fera pas plus.
number pour toutes les clés, point barre (sauf les clés "expressives" qui correspondent à une donnée, là on préfèreras un varchar ou à la limite un int si c'est vraiment un int la donnée)
a noter que sous sql server, microsoft préconise le "uniqueidentifier" comme clé...
et un GUID, c'est une série de chiffres hexadécimaux comme on en trouve plein dans la BDR, donc la valeur est imbittable et aléatoire, ceci afin d'encourager les gens à ne pas utiliser l'id comme information.
donc pas de int, surtout pas.
Marsh Posté le 18-06-2007 à 09:10:16
Finalement je vais utiliser la méthode de bignose, car celle avec la mise a jour en cascade des tables liées n'est pas possible. (trop compliqué à expliquer)
Citation : |
Par contre j'ai un pb pour la requetes update :
Je pense que l'une des deux est juste mais je sais pas laquel ...:
UPDATE toto
SET SOC_ID = ( SELECT nouv_SOC_ID
FROM lien_FK WHERE lien_FK.Ancien_SOC_ID = toto.SOC_ID)
WHERE lien_FK.Ancien_SOC_ID = toto.SOC_ID
UPDATE toto
SET SOC_ID = ( SELECT nouv_SOC_ID FROM lien_FK)
WHERE lien_FK.Ancien_SOC_ID = toto.SOC_ID
Marsh Posté le 18-06-2007 à 13:21:24
Bon et bien voilà c'est fait, je me suis lancé.
Voici ma requete de mise à jout :
UPDATE "modif histo"
SET SOC_ID = ( SELECT SOCIETE_CORRESPONDANCE.NOUV_SOC_ID
FROM SOCIETE_CORRESPONDANCE toto INNER JOIN SOCIETE_CORRESPONDANCE
ON "modif histo".SOC_ID = SOCIETE_CORRESPONDANCE.ANC_SOC_ID
WHERE toto.ANC_SOC_ID = "modif histo".SOC_ID)
Ca à l'air d'avoir marché je retrouve bien mes données où il faut et comme il faut
Ouuuffffffffffffffff
Marsh Posté le 14-06-2007 à 12:58:52
J'ai un problème:
J'ai un table sur mon SQLs erver 2005 qui a en tout 4679 enregistrement.
La clé primaire est bien défini en tant que IDENTITY commencant a 1 par incrément de 1.
Le problème est que c'est une base que j'ai récupéré d'une autre personne et je sais pas comment il c'est démerdé mais l'ID est à -2147483648 d'un coté et à 2147483647 de l'autre. Autrement dit il a atteind les 2 bornes d'un int sur 32 bits !!
HORS : au centre il y a des méga trou (forcement 4679 n'est pas égale a 2^32 )
Donc voilà mon gros problème c'est qu'il veut plus me rajouter des enregistrements car il "crois" qu'il est a la fin il me dit : Une erreur arithmétique s'est produite lors de la conversion de IDENTITY en type de données int. Débordement aithmétique."
J'ai essayé de le passer en big int ca marche niveau SQL server mais le problème c'est que j'intérroge la base avec Access et access ne supporte pas le big int et ne le comprend pas, il me met ca en texte du coup mes formulaires plante !
Helpeee je peu faire comment pour rearranger cette clef sans tout casser ?