Проблема с базой данных - внешний ключ всегда нулевой (T-SQL) - PullRequest
0 голосов
/ 12 февраля 2019

Моя проблема может быть немного длинной, чтобы описать, поскольку проект, над которым мы работаем, немного больше, но я постараюсь быть настолько точным, насколько смогу.

По сути, мы разрабатываем веб-Основы управления ранами (часть проекта для университета), где пользователь может вводить раны и устанавливать дополнительную информацию, такую ​​как размер, последовательность, загружать картинку, выбирать местоположение, ....Вся эта информация должна храниться в базе данных (мы работаем с MS SQL Studio и Visual Studio 2017), где пользователь также может получить ее позже для просмотра в модуле.

Проблема, с которой мы сталкиваемся сейчасв том, что если мы хотим показать особую рану пользователю, мы не можем заставить работать внешние ключи.Мы можем фильтровать по номеру регистра (который работает), но мы не можем фильтровать информацию о ране по ID раны (каждая рана получает уникальный идентификатор) - поэтому, если мы выбираем рану, мы все равно получаем информацию обо ВСЕХ ранах, которыесохраняются для данного регистра.

Это наша «главная таблица», где каждая рана получает уникальный идентификатор, который также является восходящим столбцом идентификации:

    [wound_id]          INT           IDENTITY (1, 1) NOT NULL,
    [wound_type]        VARCHAR (500) NULL,
    [wound_description] VARCHAR (500) NULL,
    [decuGrade]         INT           NULL,
    [wound_comments]    VARCHAR (500) NULL,
    [wound_timeReal]    DATETIME      NULL,
    [wound_timeGiven]   DATETIME      NULL,
    [casenumber]        INT           NULL,
    [username]          VARCHAR (50)  NULL,
    PRIMARY KEY CLUSTERED ([wound_id] ASC)
);

Если пользователь вводитинформация и нажимает «Далее», вызывается функция в коде, за которым заполняется таблица:

 _db.SaveWoundDetails(casenr, woundValue, decu, additional_info, realTime, givenBackDocDate, user);

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

 public void SaveWoundDetails(int casenr, string woundType, int decuGrade, string woundComment, DateTime timeReal, DateTime timeGiven , string user)
        {
            var table = ConfigurationManager.AppSettings["woundDetailsTable"];
            var insertQuery = "INSERT INTO " + table + "(casenumber, wound_type, decuGrade, wound_comments, wound_timeReal, wound_timeGiven, username) VALUES (@casenr, @woundType, @decuGrade, @woundComment, @timeReal, @timeGiven, @user)";


            var cmd = new SqlCommand(insertQuery);

            cmd.Parameters.AddWithValue("@casenr", casenr);
            cmd.Parameters.AddWithValue("@woundType", woundType);
            cmd.Parameters.AddWithValue("@decuGrade", decuGrade);
            cmd.Parameters.AddWithValue("@woundComment", woundComment);
            cmd.Parameters.AddWithValue("@timeReal", timeReal);
            cmd.Parameters.AddWithValue("@timeGiven", timeGiven);
            cmd.Parameters.AddWithValue("@user", user);
            var db = DatabaseController.getDataBaseController();

            try
            {
                var sqlcmd = db.executeSQL(cmd);
            }
            catch (SqlException e)
            {

            }
        }

Соединение и т. Д. Относится к классу Database-handler, который на данный момент неактуален.

До этого момента он работает нормально.Но теперь у нас есть вторая таблица для получения дополнительной информации о ране, которая также заполняется при следующем щелчке по этой таблице:

CREATE TABLE [dbo].[epadoc_mod_wound_progress] (
    [progress_id]       INT           IDENTITY (1, 1) NOT NULL,
    [wound_length]      INT           NULL,
    [wound_width]       INT           NULL,
    [wound_depth]       INT           NULL,
    [wound_surrounding] VARCHAR (500) NULL,
    [wound_consistence] VARCHAR (500) NULL,
    [wound_state]       VARCHAR (200) NULL,
    [wound_painscale]   VARCHAR (MAX) NULL,
    [wound_itch]        VARCHAR (MAX) NULL,
    PRIMARY KEY CLUSTERED ([progress_id] ASC)

С INSERT-METHOD:

 public void SaveWoundProgress(int woundLength, int woundWidth, int woundDepth, string woundSurrounding, string woundConsistence, string woundState, string woundPainScale, string woundItch)
        {
            var table = ConfigurationManager.AppSettings["woundProgressTable"];
            var insertQuery = "INSERT INTO " + table + "(wound_length,wound_width,wound_depth, wound_surrounding, wound_consistence, wound_state, wound_painscale, wound_itch) VALUES (@woundLength, @woundWidth, @woundDepth, @woundSurrounding, @woundConsistence, @woundState, @woundPainScale, @woundItch)";


            var cmd = new SqlCommand(insertQuery);

            cmd.Parameters.AddWithValue("@woundLength", woundLength);
            cmd.Parameters.AddWithValue("@woundWidth", woundWidth);
            cmd.Parameters.AddWithValue("@woundDepth", woundDepth);
            cmd.Parameters.AddWithValue("@woundSurrounding", woundSurrounding);
            cmd.Parameters.AddWithValue("@woundConsistence", woundConsistence);
            cmd.Parameters.AddWithValue("@woundState", woundState);
            cmd.Parameters.AddWithValue("@woundPainScale", woundPainScale);
            cmd.Parameters.AddWithValue("@woundItch", woundItch);
            var db = DatabaseController.getDataBaseController();

            try
            {
                var sqlcmd = db.executeSQL(cmd);
            }
            catch (SqlException e)
            {

            }
        }

И метод

_db.SaveWoundProgress(wound_length, wound_width, wound_depth, woundArea, woundEdge, woundStatus, painStatus, itchStatus);

, который выполняется сразу после вышеупомянутого метода.

Я знаю, как создать внешние ключи между двумя таблицами, но все, что мы пробовали, не удалось - если мы попытаемсявыполнить его с набором внешнего ключа, который НЕ равен NULL, мы получаем исключение NULL.

Пример того, что мы попробовали:

CONSTRAINT [FK_epadoc_mod_wound_details] FOREIGN KEY ([wound_id])
REFERENCES [dbo].[epadoc_mod_wound_progress] ([progress_id])

Если мы установим внешний ключ, как этот, это не сработало.

Мы пришли к выводу, что это должно быть проблемой стека вызовов при выполнении двух методов - но мы не знаем, как мы можем это исправить.Может быть, нам нужно установить внешний ключ в INSERT-запросе как явную переменную?

Чего мы хотим добиться, так это того, чтобы wound_id таблицы подробностей был взят в качестве внешнего ключа таблицы прогресса, чтобырана может быть позже изменена (например, если она излечивает, пользователь может повторно ввести новый размер и т. д.), и мы можем отфильтровать по идентификатору, чтобы показать ОДНУ рану пациенту, а не все раны одновременно, если щелкнуть мышью поспецифическая рана.

К сожалению, я не большой специалист по базам данных, поэтому я надеюсь, что вы можете следовать моим объяснениям:).

Спасибо за любую помощь!

Ответы [ 3 ]

0 голосов
/ 12 февраля 2019

Пытался добавить комментарий, но у меня нет 50 репутации.

Из того, что я вижу, я предполагаю, что вы пытаетесь достичь отношения один-ко-многим между "главным столом" и "Таблица epadoc_mod_wound_progress ", верно?

Если это так, то в таблице epadoc_mod_wound_progress нет поля, в котором хранится wound_id. Как вы пытаетесь создать внешний ключ, если вы этого не делаете?хранение wound_id?

Предложить первичный ключ таблицы epadoc_mod_wound_progress - это объединенный ключ wound_id и progress_id, причем wound_id также является внешним ключом, связывающим основную таблицу.

0 голосов
/ 12 февраля 2019

В таблице epadoc_mod_wound_progress должен быть столбец wound_id INT NOT NULL, действующий в качестве внешнего ключа.

Также необходимо добавить ограничение в таблицу внешнего ключа, то есть таблицу в n * 1006.* сторона отношения 1 к n .Предполагая, что имя основной таблицы равно epadoc_mod_wound_details (вы его не отображали):

ALTER TABLE dbo.epadoc_mod_wound_progress
ADD CONSTRAINT FK_progress_details FOREIGN KEY (wound_id)
REFERENCES dbo.epadoc_mod_wound_details (wound_id)
ON DELETE CASCADE

Кроме того, при добавлении ON DELETE CASCADE ход детали раны будет автоматически удален при удалениидеталь раны.

0 голосов
/ 12 февраля 2019

Ваш epadoc_mod_wound_progress должен содержать столбец [wound_id] INT NOT NULL.Это то, на чем должен строиться ваш внешний ключ, чтобы одна рана могла иметь много прогрессий.Затем в своем операторе вставки вы вставите wound_id, который генерируется в woundDetail вставке таблицы в epadoc_mod_wound_progress.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...