2013-03-14 24 views
0

好吧,自從我以前的post以來,我能夠取得進步!但是,我又遇到了另一個問題:T-SQL從測試移動到動態生產(第2部分)

目標:傳入兩個參數(一個任務和一個主鍵)來生成一個表的列表。獲取列表,然後動態構建插入語句,旨在將數據從生產環境複製到測試環境。換句話說,以編程方式做什麼'編輯TOP 200'呢......但速度更快。

問題(更新):@tmpInserVars沒有每次迭代更新。第一次輸入代碼時會被設置,並且不會刷新。

迄今:

USE MAINDB 
DECLARE @PK int = 1000, 
@TaskName nvarchar(50) = 'TASK', 
@curTable nvarchar(75), 
@curRow nvarchar(75), 
@tmpStatement nvarchar(500), 
@tmpInsert nvarchar(500) 

RAISERROR('Retrieving Tables',0,1) WITH NOWAIT 
DECLARE TableCursor CURSOR LOCAL FOR 

    SELECT DISTINCT TOP 2 PRMPTTBL.tTable as PromptTable 
     FROM THING1 TK INNER JOIN THING2 SC ON TK.tkNo=SC.tkNo 
       INNER JOIN Component EL on EL.scNo=SC.scNo    
       LEFT OUTER JOIN Field FLD1 on FLD1.cfNo=EL.cfNoPrompt1    
       LEFT OUTER JOIN MyTableTable MTTTBL on MTTTBL.tbNo=FLD1.tbNo 

     WHERE [email protected] 
       AND (MTTTBL.tTable is not NULL AND MTTTBL.tTable not in('OneTableIDontWant')) 
       AND MTTTBL.tTable not like '%[_]d%' --eliminate any tables that are actually views 
       AND EL.cfNo > 0 
       AND TK.Description like @TaskName 

RAISERROR('Table',0,1) WITH NOWAIT 
OPEN TableCursor 
FETCH NEXT FROM TableCursor INTO @curTable 
WHILE @@FETCH_STATUS = 0 
BEGIN 
    SET @tmpStatement = 'SELECT TOP 5 * FROM [MYCONN].TEST_MYDB.dbo.' + @curTable + ' where PK=' + Cast(@PK as nvarchar(10)) 
    EXEC (@tmpStatement) 
    RAISERROR(N'Table (outside): %s',0,1,@curTable) WITH NOWAIT 

    IF @@ROWCOUNT = 0 
    BEGIN 
     [email protected] isn't updating!!! 
     RAISERROR(N'Initial Select: %s',0,1,@tmpStatement) WITH NOWAIT 
     SELECT @tmpInsertVars = COALESCE(@tmpInsertVars + ',','') + COLUMN_NAME 
     FROM PRODDB.INFORMATION_SCHEMA.COLUMNS 
     WHERE TABLE_NAME = @curTable 

     SET @tmpInsertStatement = 'INSERT INTO [MYCONN].TEST_MYDB.dbo.' + @curTable + ' (' + @tmpInsertVars + ')' + 
            ' SELECT TOP 500 ' + @tmpInsertVars + 
            ' FROM TEST_MYDB.' + @curTable + 
            ' WHERE PK=' + Cast(@PK as nvarchar(10)) 

     RAISERROR(N'Insert Statement: %s',0,1,@tmpInsertStatement) WITH NOWAIT 
    END 


    FETCH NEXT FROM TableCursor INTO @curTable 
END 

CLOSE TableCursor 
DEALLOCATE TableCursor 

回答

1
  1. 聲明你@tmpInsertStatement和@tmpInsertVars變量。
  2. 復位@tmpInsertVars爲NULL您填充之前它

    USE MAINDB 
    DECLARE @PK int = 1000, 
    @TaskName nvarchar(50) = 'TASK', 
    @curTable nvarchar(75), 
    @curRow nvarchar(75), 
    @tmpStatement nvarchar(500), 
    @tmpInsert nvarchar(500), 
    @tmpInsertStatement nvarchar(500), 
    @tmpInsertVars nvarchar(500) 
    
    RAISERROR('Retrieving Tables',0,1) WITH NOWAIT 
    DECLARE TableCursor CURSOR LOCAL FOR 
    
        SELECT DISTINCT TOP 2 PRMPTTBL.tTable as PromptTable 
         FROM THING1 TK INNER JOIN THING2 SC ON TK.tkNo=SC.tkNo 
           INNER JOIN Component EL on EL.scNo=SC.scNo    
           LEFT OUTER JOIN Field FLD1 on FLD1.cfNo=EL.cfNoPrompt1    
           LEFT OUTER JOIN MyTableTable MTTTBL on MTTTBL.tbNo=FLD1.tbNo 
    
         WHERE [email protected] 
           AND (MTTTBL.tTable is not NULL AND MTTTBL.tTable not in('OneTableIDontWant')) 
           AND MTTTBL.tTable not like '%[_]d%' --eliminate any tables that are actually views 
           AND EL.cfNo > 0 
           AND TK.Description like @TaskName 
    
    RAISERROR('Table',0,1) WITH NOWAIT 
    OPEN TableCursor 
    FETCH NEXT FROM TableCursor INTO @curTable 
    WHILE @@FETCH_STATUS = 0 
    BEGIN 
        SET @tmpStatement = 'SELECT TOP 5 * FROM [MYCONN].TEST_MYDB.dbo.' + @curTable + ' where PK=' + Cast(@PK as nvarchar(10)) 
        EXEC (@tmpStatement) 
        RAISERROR(N'Table (outside): %s',0,1,@curTable) WITH NOWAIT 
    
        IF @@ROWCOUNT = 0 
        BEGIN 
         [email protected] isn't updating!!! 
         SELECT @tmpInsertVars = NULL; -- RESET @tmpInsertVars 
         RAISERROR(N'Initial Select: %s',0,1,@tmpStatement) WITH NOWAIT 
         SELECT @tmpInsertVars = COALESCE(@tmpInsertVars + ',','') + COLUMN_NAME 
         FROM PRODDB.INFORMATION_SCHEMA.COLUMNS 
         WHERE TABLE_NAME = @curTable 
    
         SET @tmpInsertStatement = 'INSERT INTO [MYCONN].TEST_MYDB.dbo.' + @curTable + ' (' + @tmpInsertVars + ')' + 
                ' SELECT TOP 500 ' + @tmpInsertVars + 
                ' FROM TEST_MYDB.' + @curTable + 
                ' WHERE PK=' + Cast(@PK as nvarchar(10)) 
    
         RAISERROR(N'Insert Statement: %s',0,1,@tmpInsertStatement) WITH NOWAIT 
        END 
    
    
        FETCH NEXT FROM TableCursor INTO @curTable 
    END 
    
    CLOSE TableCursor 
    DEALLOCATE TableCursor 
    
+0

哇。非常感謝!!你介意告訴我爲什麼這有效嗎?對我來說,我認爲「SELECT @tmpInsertVars = COALESCE(---)」重新指定了每次迭代的值,但事實並非如此。 – sacredfaith 2013-03-15 14:12:31

+0

tmpInsertVars變量將繼續在後續循環中保留其值,因爲賦值語句只是追加到它。 COALESCE只是在它的參數中找到它可以找到的第一個非空值。在每個後續循環中,它仍然有一個來自上次迭代的非空值,所以COALESCE語句中的第一個參數開始保留現有數據並開始附加更多數據。通過在COALESCE之前將tmpInsertVars重置爲NULL,您可以確保第一個參數/表達式將爲NULL,因爲(NULL +',')= NULL。 – 2013-03-15 14:38:26

+0

很好的解釋!謝謝!! – sacredfaith 2013-03-15 14:54:22