2015-10-19 44 views
0

我一直忙於編寫包含兩個臨時表和遊標的存儲過程。我已經收到這份任務已經兩天了,這給我一個很難的時間,因爲這是我第一次忙於編寫這樣複雜的SP。SELECT在遊標中的位置不正確導致無數個表彈出

遊標應該從DATABASE_X派生數據,並讓該數據被拿來與DATABASE_Y進行比較。

TableInfoDATABASE_Y是包含所有或大部分是在DATABASE_X模式和表的。 ColumnInfo表也是類似的情況,與TableInfo表唯一不同的是它也能夠包含列數據。

的臨時表,它們分別包含不存在的表的數據在DATABASE_Y.TableInfo和非現有列在DATABASE_Y.ColumnInfo意在比較之後將被填充。 (非現有意味着表阿在DBX存在但不是在DBY.TableInfo的行和列的情況下反之亦然)

NotInUse列存在於DATABASE_Y.TableInfo爲行列式是否應該考慮DBX中的表格進行檢查。

CREATE TABLE #NONEXISTENT_TABLES(
    SCHEMA_NAME VARCHAR(100), 
    TABLE_NAME VARCHAR(100) 
) 

CREATE TABLE #NONEXISTENT_COLUMNS(
    SCHEMA_NAME VARCHAR(100), 
    TABLE_NAME VARCHAR(100), 
    COLUMN_NAME VARCHAR(100) 
) 

DECLARE @SchemaName VARCHAR(100) 
DECLARE @TableName VARCHAR(100) 
DECLARE @ColumnName VARCHAR(100) 

USE DATABASE_X; 
DECLARE CRS_GET_NONEXISTENT_STUFF CURSOR FOR 
     select s.name as 'sname', t.name as 'tname', c.name as 'cname' 
     from sys.schemas (nolock) s 
     join sys.tables (nolock) t 
      on s.schema_id = t.schema_id 
     join sys.columns (nolock) c 
      on c.object_id = t.object_id 
     order by 1,2,3 
OPEN CRS_GET_NONEXISTENT_STUFF 

FETCH NEXT FROM CRS_GET_NONEXISTENT_STUFF INTO @SchemaName, 
               @TableName, 
               @ColumnName 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    select @SchemaName, @TableName 
    from DATABASE_Y..TableInfo (nolock) ti 
    print @SchemaName + '-' + @TableName 
    IF @@ROWCOUNT = 1 
    BEGIN 
     declare @NotInUse varchar(100) 
     select @NotInUse = ti.[NotInUse] 
     from DATABASE_Y..TableInfo (nolock) ti 
     where ti.[Schema] = @SchemaName 
     and ti.[Name] = @TableName 
     print @SchemaName + '-' + @TableName 
     IF @NotInUse = '0' 
     DECLARE @colname varchar(100) 
     BEGIN 
      select @colname = ci.[Name] 
      from DATABASE_Y..ColumnInfo (nolock) ci 
      where ci.[TableSchema] = @SchemaName 
      and ci.[TableName] = @TableName 
      and ci.[Name] = @ColumnName 
      print @SchemaName + '-' + @TableName + '-' + @ColumnName 
      IF @colname IS NULL 
      BEGIN 
       INSERT INTO #NONEXISTENT_COLUMNS(SEMA_ADI, TABLO_ADI, KOLON_ADI) 
       VALUES(@SchemaName, @TableName, @colname) 
      END 
     END 
    END 
    ELSE 
     INSERT INTO #NONEXISTENT_TABLES(SCHEMA_NAME, TABLE_NAME) 
     VALUES (@SchemaName, @TableName) 
    FETCH NEXT FROM CRS_GET_NONEXISTENT_STUFF INTO @SchemaName, 
               @TableName, 
               @ColumnName 
END 

CLOSE CRS_GET_NONEXISTENT_STUFF 
DEALLOCATE CRS_GET_NONEXISTENT_STUFF 

SELECT * FROM #NONEXISTENT_COLUMNS 

SELECT * FROM #NONEXISTENT_TABLES 


DROP TABLE #NONEXISTENT_COLUMNS 


DROP TABLE #NONEXISTENT_TABLES 

假設: *上DBX的第一個模式是AAA和AAA的DBX是BBBBB * AAA的第二個表是CCCCC第一表;

我收到了無數的表格,其結果是看起來很像看起來很快就會很快查詢,在5-6個表格中只顯示5000行左右的AAA-BBBBB,然後移動到AAA-CCCCC正在做上面發生的事情,並且繼續下去。

我相信我的錯誤是把那個WHILE循環下的SELECT命令,但我也相信,這是不是我唯一的錯誤...

我會很感激有大家的意見關於這個問題。

對於純粹的文字牆,我表示歉意。

+0

在腳本錯誤上面使我收到表的無限量,我必須解決這個問題......這是基本的問題。 我應該只收到兩個最終表格,這些表格是不存在的表格和不存在的表格。 –

+0

那麼刪除/註釋足夠的代碼,你會發現它被卡住的原因,一旦你知道是什麼原因造成的,請修復它。 –

+0

我覺得我應該發佈整個代碼,因爲我不熟悉語法......我不確定是否我有多個錯誤。 –

回答

1

我建議的第一件事是讀這篇文章 - Bad habits : Putting NOLOCK everywhere

接下來的事情是,每個循環運行此:

select @SchemaName, @TableName 
from DATABASE_Y..TableInfo (nolock) ti; 

print @SchemaName + '-' + @TableName; 

IF @@ROWCOUNT = 1 
.... 

我增加了換行和清晰度語句結束,但第一個選擇就是你所得到的結果集的負載。這不會執行任何操作,並會針對數據庫中的每一列運行。此外,你有IF @@ROWCOUNT = 1它將始終返回0,因爲它遵循打印命令,它不返回行。所以你永遠不會輸入這個IF/ELSE塊的「真實」部分。

我敢肯定,你不需要光標可言的,作爲一般規則,除非你絕對必須使用你不應該使用一個遊標。所以我覺得你可以簡單地基於兩組刀片更換所有的循環:

CREATE TABLE #NONEXISTENT_TABLES(
    SCHEMA_NAME VARCHAR(100), 
    TABLE_NAME VARCHAR(100), 
    object_id INT NOT NULL 
); 

CREATE TABLE #NONEXISTENT_COLUMNS(
    SCHEMA_NAME VARCHAR(100), 
    TABLE_NAME VARCHAR(100), 
    COLUMN_NAME VARCHAR(100) 
); 

INSERT #NONEXISTENT_TABLES (SCHEMA_NAME, TABLE_NAME, objecobject_idt_ID) 
SELECT s.name, t.Name, object_id 
FROM sys.tables AS t 
     INNER JOIN sys.schemas AS s 
      ON s.schema_id = t.schema_id 
WHERE NOT EXISTS 
     ( SELECT 1 
      FROM DATABASE_Y..TableInfo AS ti 
      WHERE ti.TableSchema = s.Name 
      AND  ti.name = t.name 
      --AND  ti.NotInUse = 0 
     ); 

INSERT #NONEXISTENT_COLUMNS (SCHEMA_NAME, TABLE_NAME, COLUMN_NAME)  
SELECT nt.SCHEMA_NAME, nt.TABLE_NAME, c.name 
FROM sys.columns AS c 
     INNER JOIN #NONEXISTENT_TABLES AS nt 
      ON nt.object_id = c.object_id); 
+0

應該是'NOT EXISTS',因爲他們想要那些不在TableInfo中的,但絕對不需要爲此使用光標。 –

+0

@AnthonyGG是的,我認爲你是對的,我正在努力從原來的帖子拿起意圖。重新閱讀這篇文章後,我已根據您的建議進行了編輯。謝謝。 – GarethD

+0

我的老師特別希望我用遊標來做,以便讓我對temptables和遊標都有所瞭解。儘管如此,我真的很感謝你的答覆,並會盡快開始審查。 –

相關問題