2012-05-17 13 views
6

Bu, muhtemelen sınırlı, ancak değerli bir senaryodur. Milyonlarca kaydı olan bir tablonun bulunduğu bir SQL Server 2008 veritabanım var. Kayıtların bir kısmında aralıklı bir sorun var gibi görünüyor. Sorunu yeniden araştırmaya çalışıyorum. Bunu yapmak için bir çaba sonunda nihayet bir suç işlemenin kimliğini aldım. PROD veritabanımda bu tek kayıtla ilişkili bir INSERT ifadesi oluşturmak istiyorum. Ardından sorunu yeniden çözümlemek ve çözmek için TESTING veritabanına kolayca taşıyabilirim.SQL Server'daki Belirli Kayıtlar için Komut Dosyaları Oluşturma

Temelde, ben kaydın birincil anahtar değerini bilmek tek tablodan tek bir kayıt için tek bir INSERT deyimi oluşturmak gerekiyor.

Bunu nasıl başarabileceğime dair herhangi bir fikrim var mı? Esasen, koşullu olarak ekleme ifadeleri oluşturmak istiyorum.

Teşekkür ederiz!

+1

tablo şema? koşullar? Burada çok zeki insanlar var ama bunların hiçbiri peygamber değil: P –

+0

Sadece soruyu güncelledim. Teşekkürler. – user70192

cevap

4

İlk olarak, SELECT ifadesiyle eklemek istediğiniz şeyi yeniden oluşturmayı deneyin.

Bundan sonra böyle bir INSERT INTO ile tabloya ekleyebilirsiniz: kullanarak

INSERT INTO tablename VALUES (...) 

: Farklı sunucularda ise, böyle INSERT kullanabilirsiniz

INSERT INTO tablename 
SELECT .... 

Diğer sunucudaki SELECT tarafından verilen değerler, ek içindeki değerleri doldurur. Belirli bir durumda

+0

Bunlar farklı sunuculardaysa, bu bir bağlantılı sunucu gerektirir.Bu fikri daha çok beğendim ama OP'nin başka bir yere kopyalamak, yapıştırmak ve yürütmek için değerleri olan bir statik dizge oluşturmaya çalıştığını düşünüyorum. –

+0

@AaronBertrand bu doğru! Bu bilgileri eklemek için düzenledim. –

+0

Mükemmel Efendim! çok değerli bir cevap. –

5

ben bunu düşünüyorum:

CREATE 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 + ' + ' + REPLICATE(CHAR(39),3) + ',' 
      + REPLICATE(CHAR(39),3) + ' + ' + REPLICATE(CHAR(39),2) + '+' 
      + 'RTRIM(' + CASE WHEN system_type_id IN (40,41,42,43,58,61) THEN 
      'CONVERT(CHAR(8), ' + QUOTENAME(name) + ', 112) + '' '' 
      + CONVERT(CHAR(14), ' + QUOTENAME(name) + ', 14)' 
      ELSE 'REPLACE(' + QUOTENAME(name) + ','''''''','''''''''''')' END + ') 
      + ' + REPLICATE(CHAR(39),2) 
     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), 4) + ' + ' + STUFF(@vals, 1, 13, '') 
      + 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 
GO 

Öyleyse bunu deneyelim:

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' 

için SET ıdentıty_ınsert ON ayarlamak gerekebilir bir KİMLİK sütun varsa TEST tablosunu ve çarpışma olmadığını doğrulayın. Muhtemelen bahsetmem gereken yaklaşık 500 uyarı söz konusudur, tüm veri türlerini test etmedim, vb.

Bununla birlikte, daha genel durumda bundan daha fazla lot var.

http://vyaskn.tripod.com/code/generate_inserts_2005.txt

Muhtemelen belirli satır almak ve sizin için bir ek parça üretmek için Red-Gate's SQL Data Compare gibi bir araç kullanarak çok daha iyi şunlardır: Vyas K alabileceği kadar karmaşık göstermelidir oldukça sağlam saklı yordamı vardır. As I've blogged about, bir araç için ödeme sadece para ile ilgili değil, birisinin sizin için zaten yapmış olduğu sorun giderme ve hata düzeltme saatleri hakkında.

+0

Yukarıda yazdığınız kodda bazı değişiklikler yapmam gerekiyordu (teşekkürler btw). Bir yorum için büyüktü ve ben yazı ekledim kodu göremediğinden emin değilim, bu yüzden aşağıda ekledim. – RobRolls

2

Aaron, kodunuzu sevdim , benim için bir sorun çözüldü. Ben nulls ve metin türünü kullanarak (sizin dediğim gibi) kullanarak birkaç sorunları yaşadım, bu yüzden bu sorunları çözmek için bazı değişiklikler yaptım.

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 
İlgili konular