дубликат первичного ключа в таблице возврата, созданной в select union - PullRequest
0 голосов
/ 29 февраля 2012

У меня есть следующий запрос под названием searchit

SELECT 2 AS sourceID, BLOG_COMMENTS.bID, BLOG_TOPICS.Topic_Title,
    BLOG_TOPICS.LFD, BLOG_TOPICS.LC,
    BLOG_COMMENTS.Comment_Narrative
FROM BLOG_COMMENTS INNER JOIN BLOG_TOPICS
    ON BLOG_COMMENTS.bID = BLOG_TOPICS.bID
WHERE  (BLOG_COMMENTS.Comment_Narrative LIKE @Phrase)

Этот запрос выполняется И возвращает правильные результаты в построителе запросов!ОДНАКО запрос должен выполняться с выделенным кодом, поэтому у меня есть следующая строка:

DataTable blogcomments = btad.searchit(aphrase);

Нет пустых полей ни в одной строке любого столбца в ЛЮБОЙ из таблиц.Таблицы достаточно малы, я могу легко обнаружить нулевые данные.Обратите внимание, что bID является ключевым для blog_topics, а cID является ключевым для комментариев в блоге.

В любом случае, когда я запускаю это, я получаю следующую ошибку:

Не удалось включить ограничения.Одна или несколько строк содержат значения, нарушающие ограничения ненулевого, уникального или внешнего ключа.

Таблицы имеют отношение 1 x N, много комментариев для каждой записи в блоге.ЕСЛИ я запускаю запрос с DISTINCT и удаляю Comment_Narrative из полей возврата, он возвращает данные правильно (но мне нужны другие строки!) Однако, когда я возвращаю другие строки, я получаю вышеуказанную ошибку!

Я думаю, что говорит мне, что есть ограничение на возвращаемую таблицу, которое я не поместил туда, поэтому оно должно каким-то образом наследовать это ограничение от вызова самого запроса, потому что в одной из таблиц определен первичный ключ (которыйДолжен иметь).Но почему запрос отлично работает в построителе запросов?Построитель запросов не заботится о том, что bID дублируется в результате (и не должно быть), но код, стоящий за ним, заботится.

Приложение:

Так же, как тесты,

  1. Я удалил bID из списка возврата и все еще получаю ошибку.
  2. Я удалил первичный ключ из blog_topics.bID и получаю ту же ошибку.

Это как бы говорит мне, что не факт, что мой bID дублирован, вызывает проблему.

Еще один тест: я вошел в код конструктора (я знаю, что это противно, я просто в отчаянии).Я добавил следующее:

    // zzz
    try
    {

        this.Adapter.Fill(dataTable);
    }
    catch ( global::System.Exception ex )
    {

    }

Как ни странно, когда я запускаю его, я получаю ту же ошибку, что и раньше, и он не показывает изменения, которые я внес в сообщение об ошибке:

Line 13909:            }
Line 13910:            BPLL_Dataset.BLOG_TOPICSDataTable dataTable = new BPLL_Dataset.BLOG_TOPICSDataTable();
Line 13911:            this.Adapter.Fill(dataTable);
Line 13912:            return dataTable;
Line 13913:        }

Я в замешательстве .... Если, возможно, он не видит, что я ничего не делаю в try-улове и оптимизирует для меня.

Еще одно дополнение: Подозреваю, что он игнорировал тестовый кодЯ добавил в конструктор, я добавил что-то в улов.Он выдает ОДНУ ЖЕ ошибку и действует так, как будто не видит этот код.(Ну, ладно, он НЕ видит этот код, потому что он печатает так же, как и раньше, в браузер.)

    // zzz
    try
    {

        this.Adapter.Fill(dataTable);
    }
    catch ( global::System.Exception ex )
    {
        System.Web.HttpContext.Current.Response.Redirect("errorpage.aspx");
    }

Дело в том, что когда я сделал исходное сообщение, я уже пытался сделатьобходной путь.Я не уверен, насколько далеко я могу позволить себе пройти по кроличьей норе.Может быть, я прочитал весь беспорядок в C # и сделать все соединения и обосрался.Я действительно очень не хочу этого делать, потому что я только недавно вышел из привычки, но я чувствую, что прилагаю добросовестные усилия, чтобы использовать этот инструмент так, как задумал Бог и Microsoft.С конца ума, tff.

Ответы [ 2 ]

1 голос
/ 29 февраля 2012

Вы на самом деле не показываете, как вы выполняете этот запрос из C # ... но я предполагаю, что либо в виде простого текста в SqlCommand, либо это делается каким-то ORM ... Вы пытались написать этот запрос в качестве хранимой процедуры и называть это так? Хранимая процедура будет проще тестировать и запускать сама с примерами данных.

Учитывая тот факт, что в ошибке упоминаются нулевые значения, я бы предположил, что, если это проблема с запросом, а не каким-либо другим элементом вашего кода, то он должен находиться в одном из следующих полей: BLOG_COMMENTS.bID BLOG_TOPICS.bID BLOG_COMMENTS.Comment_Narrative

Если какое-либо из этих полей имеет значение Nullable, вам следует использовать COALESCE или ISNULL для них, прежде чем использовать их в любом сравнении или соединении. Именно такие ситуации объясняют, почему большинство администраторов баз данных предпочитают иметь в таблицах как можно меньше столбцов, которые могут содержать пустые значения - они вызывают накладные расходы и подвержены ошибкам.

Если это по-прежнему не решает вашу проблему, тогда COALESCE / ISNULL все поля, которые могут быть обнуляемыми и которые возвращаются этим запросом. Возьмите все нулевые значения из уравнения и просто работайте, а затем, если вам действительно нужно, чтобы нулевые значения были нулевыми, вернитесь назад и удалите COALESCE / ISNULL по одному, пока не найдете виновника.

0 голосов
/ 16 марта 2012

Моя проблема возникла из-за невежества и немного тупости. Я не осознавал, что только потому, что поле является ключом в таблице sql, это означает, что оно должно быть ключом в табличном адаптере. Если в таблице SQL определено ключевое поле, а затем создан адаптер таблицы, соответствующее поле в адаптере также будет ключевым. Все, что мне нужно было сделать, это сбросить ключевое поле в табличном адаптере, и это сработало.

Решение:

  • Выберите ключевое поле в адаптере.
  • Правый клик
  • Выберите «Удалить ключ» (сохраняет поле, но удаляет значок «ключ»)

Вот и все.

...