2015-10-19 3 views
0

Я занимался кодированием хранимой процедуры, которая содержит две временные таблицы и курсор. Прошло два дня с тех пор, как я получил это задание, и мне тяжело, потому что я впервые занимаюсь кодированием SP такой сложности.Неправильное размещение SELECT в курсоре вызывает появление большого количества таблиц

Курсор должен выводить данные из DATABASE_X и позволяет получать данные для сравнения с DATABASE_Y.

TableInfo стол в DATABASE_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 ААА и первый стол на DBX ААА является BBBBB * Вторая таблица ААА является CCCCC;

Я получаю бесчисленное количество таблиц в результате запроса с чуть-чуть-чуть-похожим на бытие-конец, имеющего только AAA-BBBBB, отображаемый в 5-6 таблицах с примерно 5000 строк, а затем переход на AAA-CCCCC делает то, что произошло выше, и оно продолжается и продолжается.

Я считаю, что моя ошибка была поставить выбора команд в соответствии с этим время цикла, но я также считаю, что это была не моя единственная ошибка ...

Я ценю имея советы всех вас об этом проблема.

Прошу прощения за простую стену текста.

+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

Возможно, должно быть 'НЕ СУЩЕСТВУЕТ', так как они хотят тех, которые не указаны в таблице. , но определенно нет необходимости использовать курсор для этого. –

+0

@ AnthonyGrist Да, я думаю, вы правы, я изо всех сил пытался понять намерение с оригинального поста. Перечитав это, я отредактировал по вашему предложению. Благодарю. – GarethD

+0

Мой инструктор особенно хотел, чтобы я сделал это с помощью курсоров, чтобы у меня появилась идея об искушениях и курсорах. Тем не менее, я действительно ценю ваш ответ и начну рассматривать его как можно скорее. –

Смежные вопросы