8
votes

Générer des scripts pour des enregistrements spécifiques dans SQL Server

Ceci est probablement un peu un scénario limité mais précieux. J'ai une base de données SQL Server 2008 avec une table contenant des millions d'enregistrements. Il semble y avoir un problème intermittent avec plusieurs des enregistrements. J'essaie de reproduire le problème. Dans un effort pour le faire, j'ai enfin obtenu l'identifiant d'un enregistrement fautif. Je souhaite générer une instruction insertion associée à cet enregistrement unique dans ma base de données Prod. Ensuite, je peux facilement la migrer dans ma base de données de test dans un effort de reproduction et résoudre le problème.

Fondamentalement, j'ai besoin de générer une seule instruction insert pour un seul enregistrement d'une seule table dans laquelle je connais la valeur de clé principale de l'enregistrement.

Quelqu'un a-t-il des idées sur la façon dont je peux accomplir cela? Essentiellement, je veux générer des relevés d'insertion sur une base conditionnelle.

Merci!


2 commentaires

schéma de table? conditions? Il y a de jolies personnes intelligentes ici, mais aucun d'entre eux n'est des prophètes: p


Je viens de mettre à jour la question. Merci.


3 Réponses :


5
votes

Essayez d'abord de recréer ce que vous souhaitez insérer avec une instruction CODE> SELECT CODE>.

Après cela, vous pouvez insérer dans la table avec un insérer dans code> comme ceci: xxx pré>


S'ils sont sur différents serveurs, vous pouvez utiliser Insérer comme ceci: p>

INSERT INTO tablename VALUES (...)


2 commentaires

Si ceux-ci sont sur différents serveurs, cela nécessitera un serveur lié. J'aime bien cette idée, mais je pense que l'OP tente de générer une chaîne statique avec des valeurs pour copier, coller et exécuter ailleurs.


Excellent monsieur! réponse très précieuse.



5
votes

Dans votre cas spécifique, je pense que vous pouvez le faire:

CREATE TABLE dbo.splunge
(
    ID INT, dt DATETIME, rv ROWVERSION, t NVARCHAR(MAX)
);

INSERT dbo.splunge(ID, dt, t)
          SELECT 1, GETDATE(), 'foo'
    UNION ALL SELECT 2, GETDATE(), 'bar'
    UNION ALL SELECT 3, GETDATE(), 'O''Brien';

EXEC dbo.GenerateSingleInsert N'dbo.splunge', N'ID', 1;

SQL
-------------
INSERT dbo.splunge([ID],[dt],[t]) SELECT '1','20120517 10:07:07:330','foo'

EXEC dbo.GenerateSingleInsert N'dbo.splunge', N'ID', 2;

SQL
-------------
INSERT dbo.splunge([ID],[dt],[t]) SELECT '2','20120517 10:07:07:330','bar'

EXEC dbo.GenerateSingleInsert N'dbo.splunge', N'ID', 3;

SQL
-------------
INSERT dbo.splunge([ID],[dt],[t]) SELECT '3','20120517 10:07:07:330','O''Brien'


1 commentaires

J'avais besoin de modifier le code que vous avez écrit ci-dessus (merci BTW). C'était grand pour un commentaire et je n'étais pas sûr de l'étiquette lors de la modification du code dans votre message, donc je l'ai ajouté ci-dessous.



2
votes

Aaron, J'ai aimé votre code, cela m'a résolu un problème pour moi. J'ai rencontré quelques problèmes en l'utilisant (comme si vous avez dit que je voudrais) avec des nulls et le type de texte, donc j'ai apporté des modifications à résoudre ces problèmes.

ALTER PROCEDURE dbo.GenerateSingleInsert
@table     NVARCHAR(511), -- expects schema.table notation
@pk_column SYSNAME,       -- column that is primary key
@pk_value  INT            -- change data type accordingly
AS
BEGIN
SET NOCOUNT ON;

DECLARE @cols   NVARCHAR(MAX), @vals   NVARCHAR(MAX),
        @valOut NVARCHAR(MAX), @valSQL NVARCHAR(MAX);

SELECT @cols = N'', @vals = N'';

SELECT @cols = @cols + ',' + QUOTENAME(name),
       @vals = @vals + ' + '','' + ' + 'ISNULL('+REPLICATE(CHAR(39),4)+'+RTRIM(' + 
                                        CASE WHEN system_type_id IN (40,41,42,43,58,61) -- datetime types
                                        THEN
                                            'CONVERT(CHAR(8), '  + QUOTENAME(name) + ', 112) + '' ''+ CONVERT(CHAR(14), ' + QUOTENAME(name) + ', 14)'
                                        WHEN system_type_id IN (35) -- text type NOTE: can overflow
                                        THEN
                                            'REPLACE(CAST(' + QUOTENAME(name) + 'as nvarchar(MAX)),'+REPLICATE(CHAR(39),4)+','+REPLICATE(CHAR(39),6)+')' 
                                        ELSE 
                                            'REPLACE(' + QUOTENAME(name) + ','+REPLICATE(CHAR(39),4)+','+REPLICATE(CHAR(39),6)+')' 
                                        END 
                                + ')+' + REPLICATE(CHAR(39),4) + ',''null'') + '

  FROM sys.columns WHERE [object_id] = OBJECT_ID(@table)
  AND system_type_id <> 189 -- can't insert rowversion
  AND is_computed = 0;      -- can't insert computed columns

SELECT @cols = STUFF(@cols, 1, 1, ''),
       @vals = REPLICATE(CHAR(39),2) + STUFF(@vals, 1, 6, '') + REPLICATE(CHAR(39),2) ;

SELECT @valSQL = N'SELECT @valOut = ' + @vals + ' FROM ' + @table + ' WHERE '
    + QUOTENAME(@pk_column) + ' = ''' + RTRIM(@pk_value) + ''';';

EXEC sp_executesql @valSQL, N'@valOut NVARCHAR(MAX) OUTPUT', @valOut OUTPUT;

SELECT SQL = 'INSERT ' + @table + '(' + @cols + ') SELECT ' + @valOut;
END


0 commentaires