IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MS SQL Server Discussion :

Copier une table avec IDENTITY_INSERT


Sujet :

MS SQL Server

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2003
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 211
    Par défaut Copier une table avec IDENTITY_INSERT
    Salut,

    J'essai de recopier une table comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SET IDENTITY_INSERT Table1 ON;
    INSERT INTO Table1 SELECT * FROM Table2;
    SET IDENTITY_INSERT Table1 OFF;
    Mais ça ne fonctionne pas.
    Si j'enlève l'autoincrément à la main sur la table la ligne de copie fonctionne.

    Comment faire avec des requêtes SQL ?

    D'avance merci

  2. #2
    Membre Expert
    Avatar de rudib
    Homme Profil pro
    Fakir SQL Server & NoSQL
    Inscrit en
    Mai 2006
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Fakir SQL Server & NoSQL

    Informations forums :
    Inscription : Mai 2006
    Messages : 2 573
    Par défaut
    Bonjour,

    Comment sais-tu que ça ne marche pas ? Message d'erreur ? Lequel ?
    L'utilisateur qui exécute cela a-t-il des droits au moins ddladmin sur la base ?

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2003
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 211
    Par défaut
    Oui j'ai un message d'erreur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [Microsoft][ODBC SQL Server Driver][SQL Server]Une valeur explicite e la colonne identité de la table 'Base1..Table1' ne peut être spécifiée que si on fait appel à la liste des colonne et si IDENTITY_INSERT est ON.
    (ma table se situe sur une autre base).

    Pour ce qui est des droits pour l'instant j'effectue mes tests avec le l'utilisateur "sa" qui a tous les droits.

    (question subsidiaire comment on fait si la base est carrément sur un autre serveur ?)

  4. #4
    Membre Expert
    Avatar de rudib
    Homme Profil pro
    Fakir SQL Server & NoSQL
    Inscrit en
    Mai 2006
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Fakir SQL Server & NoSQL

    Informations forums :
    Inscription : Mai 2006
    Messages : 2 573
    Par défaut
    Bon, eh bien comme l'indique le message d'erreur, il faut que tu fasses ton INSERT en mentionnant explicitement tes colonnes, ce que tu devrais d'ailleurs toujours faire.

    Pour un autre serveur, tu peux utiliser le mécanimse des serveurs liés. Regarde serveur lié ou linked server dans l'aide en ligne.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2003
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 211
    Par défaut
    bah lister toutes les colonnes c'est bien gentil mais si j'enlève l'histoire d'autoincrémentation ça marche sans ça.

    Et vu que je dois faire le travail pour presque 50 tables et que chacune possède de nombreux champs j'ai pas envie de perdre du temps avec ça (ou alors on peut lister les champs avec une requête de manière générique mais ça je ne sais pas faire).

    merci pour les réponses en tous les cas.

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    434
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 434
    Par défaut
    Citation Envoyé par [DreaMs]
    bah lister toutes les colonnes c'est bien gentil mais si j'enlève l'histoire d'autoincrémentation ça marche sans ça.

    Et vu que je dois faire le travail pour presque 50 tables et que chacune possède de nombreux champs j'ai pas envie de perdre du temps avec ça (ou alors on peut lister les champs avec une requête de manière générique mais ça je ne sais pas faire).

    merci pour les réponses en tous les cas.
    Salut,

    en fait c'est plus simple que cela... En tout cas à comprendre l'erreur ; faire un "insert into... select *" sur des tables qui ont une colonne IDENTITY est une erreur... Car, en schématisant, tu demandes à mettre la même valeur identity dans ta table destination que dans ta table source. Or, ceci est faux conceptuellement

    C'est pour cela que SQL server te dit de lister explicitement toutes les colonnes des tables, sauf celle(s) identity.

    POur faire ce genre de script automatiquement, c'est assez simple. Il suffit de faire un curseur sur sysobjects puis de faire une jointures sur syscolumns et de récupérer le nom des colone dans Xtype <> identity.

    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    create table source (idd int not null identity(1,1), val varchar(10) not null, val3 varchar(10) not null)
    create table dest (idi int not null identity(1,1), val5 varchar(10) not null, val10 varchar(10) not null)
     
    insert into source select 'test', 'avant'
     
     
     
    declare @sql nvarchar(4000)
    declare @col sysname
    set @sql = 'INSERT INTO dest SELECT '
     
    declare cur_col cursor for
    select c.name from syscolumns c inner join sysobjects o
    on o.id = c.id
    where o.name = 'source'
    and c.xtype <>56
     
    open cur_col
    fetch next from cur_col into @col
    while (@@FETCH_STATUS =0)
    BEGIN
    	SET @SQL = @SQL + @col +', '
    	fetch next from cur_col into @col
    END
    close cur_col
    deallocate cur_col
    set @SQL = LEFT(@SQL, LEN(@SQL) -1) + ' FROM source'
     
    exec (@sql)
     
    select * from dest
    CDlt

  7. #7
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 22 029
    Billets dans le blog
    6
    Par défaut
    Passez par du SQL dynamique :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    DECLARE @SQL VARCHAR(8000)
     
    DECLARE C CURSOR
    FOR
       SELECT TABLE_NAME 
       FROM INFORMATION_SCHEMA.TABLES
     
    OPEN C
     
    FECTH C INTO @SQL
     
    WHILE @@FECTH_STATUS = 0
    BEGIN
       SET @SQL =   'SET IDENTITY_INSERT ' + TABLE_SCHEMA + '.' + TABLE_NAME +' ON; '
                  + 'INSERT INTO '+ TABLE_SCHEMA + '.' + TABLE_NAME + ' SELECT * FROM ' + TABLE_SCHEMA + '.' + TABLE_NAME +'2;'
                  + 'SET IDENTITY_INSERT ' + TABLE_SCHEMA + '.' + TABLE_NAME +' OFF; '
       EXEC (SQL)
     
       FECTH C INTO @SQL
     
    END
     
    CLOSE C
     
    DEALLOCATE C
    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Novembre 2006
    Messages : 11
    Par défaut
    Bonjour,
    Dans le même ordre d'idée, je dois importer une base Oracle vers Mssql 2000 par l'assistant DTS. Ce sont strictement les mêmes base de données (tables et colonnes).
    Il faudrait que je puisse inhiber les colonnes Identity sous SQL2000 afin de récupérer les valeurs d'Oracle et comme il y a + de 350 tables, je ne veux pas aller dans les options d'importation pour chacune d'entre elles.

    J'ai essayé de modifier le type de colonnes des tables SQL 200 au préalable:

    set @DynamicSQL = 'SET IDENTITY_INSERT '+ @table + ' ON '
    execute (@DynamicSQL)

    Mais cela n'est pas appliqué lors du DTS.

    Quelqu'un aurat-il une idée ?
    D'avance un grand merci

  9. #9
    Membre Expert
    Avatar de rudib
    Homme Profil pro
    Fakir SQL Server & NoSQL
    Inscrit en
    Mai 2006
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Fakir SQL Server & NoSQL

    Informations forums :
    Inscription : Mai 2006
    Messages : 2 573
    Par défaut
    Il n'y a pas de moyen d'enlever par script la propriété identity. Tu peux tout importer dans une base de donnée temporaire, et ensuite faire un insert dans tes tables destination en utilisant le SQL dynamique fourni par SQLPro.

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Novembre 2006
    Messages : 11
    Par défaut

    Ok merci

  11. #11
    Membre habitué
    Inscrit en
    Octobre 2007
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 11
    Par défaut
    Bonjour,

    Je relance le sujet car je ne comprends pas tout dans le script de SQLPro.

    SELECT TABLE_NAME
    FROM INFORMATION_SCHEMA.TABLES

    Dans SELECT il met un nom de table et pas un nom de colonne. Est-ce normale?

    Que veux-t-il dire dans l'instruction?
    FROM INFORMATION_SCHEMA.TABLES

    Merci.

    Ps: Je suis débutant en SQL server 2005

  12. #12
    Membre Expert
    Avatar de rudib
    Homme Profil pro
    Fakir SQL Server & NoSQL
    Inscrit en
    Mai 2006
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Fakir SQL Server & NoSQL

    Informations forums :
    Inscription : Mai 2006
    Messages : 2 573
    Par défaut
    Ce sont des vues d'information de schéma, définies par la norme SQL. Une règle des bases de données relationnelles, est de maintenir leurs métadonnées dans des tables, comme des données, ce qui permet des requêtes sur les métadonnées.

    http://sqlserver.developpez.com/faq/?page=Schema

  13. #13
    Membre habitué
    Inscrit en
    Octobre 2007
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 11
    Par défaut
    Merci.

    En fait il y avait une erreur de frappe pour le FETCH.
    une fois corrigé j'ai pu comprendre le select.

    J'aurai du enlever ma question.
    Désolé.

Discussions similaires

  1. Copier une table avec sa ou ses clés primaires
    Par Nitromard dans le forum VBA Access
    Réponses: 1
    Dernier message: 27/04/2011, 14h50
  2. Réponses: 11
    Dernier message: 20/03/2007, 01h13
  3. Copier une table vers une autre et classer avec PHP
    Par Alexandrebox dans le forum Débuter
    Réponses: 12
    Dernier message: 30/01/2007, 10h01
  4. [MySQL] Copier une table vers une autre et classer avec PHP
    Par Alexandrebox dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 29/01/2007, 19h38
  5. Copier Coller une ligne d'une table avec modif ?
    Par nolan76 dans le forum Requêtes
    Réponses: 4
    Dernier message: 04/03/2004, 17h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo