Еще одна ошибка при конвертации: не удалось преобразовать строку символов в uniqueidentifier.

Вопрос или проблема

В любом случае, это SQL Server Management Studio 2022. Ошибка возникает только во время выполнения и только когда я щелкаю правой кнопкой мыши на сохраненной процедуре в списке и выбираю выполнение.

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

DECLARE IndexCursor CURSOR FOR
    SELECT PersonID AS NewUserID
    FROM Person as tblUser

OPEN IndexCursor
FETCH NEXT FROM IndexCursor INTO @UserID

INSERT INTO Workout (PersonID, ExerciseID, ExerciseTypeID)
    SELECT *
    FROM Exercise A
    WHERE NOT EXISTS (SELECT @UserID, A.ExcerciseID, A.ExerciseTypeID
                      FROM Workout B
                      WHERE A.ExcerciseID = B.ExerciseID
    )

Я сузил проблему до предложения WHERE. Если я закомментирую это, я не получаю ошибку, но также это выполняется на всех данных.

Это выполняет курсор, чтобы захватить каждый userid и захватить его, чтобы он мог использоваться для заполнения таблицы тренировок. Другие данные уже находятся в таблице упражнений.

Идея в том, что если упражнение добавляется, оно будет добавлено к тренировкам каждого человека в базе данных. Все поля и переменные установлены как уникальные идентификаторы, поэтому я действительно не знаю, почему нужно преобразовывать что-то в то, что уже должно быть установлено.

Я нашел одно различие в двух полях предложения WHERE, но не знаю, как это исправить. B.ExerciseID имеет значение по умолчанию (newid()), A.exercise столбец не имеет.

Я знаю, что у меня есть опечатки в слове “упражнение”, мне нужно зайти и исправить это. лол

Я попробовал CAST и CONVERT на @UserID во всех случаях, когда он появляется. Я пробовал CAST на A.Exercise и B.Exercise, поочередно и одновременно. Я искал и искал, гугляя различные идеи. Я закомментировал части кода, чтобы сузить фактическую строку, вызывающую проблему (только когда я это сделал, я понял, что переменная @UserID на самом деле не вызывала проблему)

Обновление:

USE [WorkoutTracker]
GO

/****** Объект:  Таблица [dbo].[Person]    Дата скрипта: 10/27/2024 10:02:40 PM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Person](
    [PersonID] [uniqueidentifier] NOT NULL,
    [Name] [varchar](50) NOT NULL,
    [Weight] [smallint] NOT NULL,
    [GoalWeight] [smallint] NOT NULL,
 CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED 
(
    [PersonID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO

USE [WorkoutTracker]
GO

/****** Объект:  Таблица [dbo].[Workout]    Дата скрипта: 10/27/2024 10:04:05 PM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Workout](
    [WrokoutID] [uniqueidentifier] NOT NULL,
    [PersonID] [uniqueidentifier] NOT NULL,
    [ExerciseID] [uniqueidentifier] NOT NULL,
    [ExerciseTypeID] [uniqueidentifier] NOT NULL,
    [Weight] [smallint] NOT NULL,
    [Reps] [smallint] NOT NULL,
    [Sets] [smallint] NOT NULL,
    [NumberOfTimesCompleted] [bigint] NOT NULL,
    [DateOfLastCompletion] [date] NOT NULL,
    [Notes] [nvarchar](max) NULL,
 CONSTRAINT [PK_Workout] PRIMARY KEY CLUSTERED 
(
    [WrokoutID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

ALTER TABLE [dbo].[Workout] ADD  CONSTRAINT [DF_Workout_WrokoutID]  DEFAULT (newid()) FOR [WrokoutID]
GO

ALTER TABLE [dbo].[Workout] ADD  CONSTRAINT [DF_Workout_ExerciseID]  DEFAULT (newid()) FOR [ExerciseID]
GO

ALTER TABLE [dbo].[Workout] ADD  CONSTRAINT [DF_Workout_Weight]  DEFAULT ((0)) FOR [Weight]
GO

ALTER TABLE [dbo].[Workout] ADD  CONSTRAINT [DF_Workout_Reps]  DEFAULT ((0)) FOR [Reps]
GO

ALTER TABLE [dbo].[Workout] ADD  CONSTRAINT [DF_Workout_Sets]  DEFAULT ((0)) FOR [Sets]
GO

ALTER TABLE [dbo].[Workout] ADD  CONSTRAINT [DF_Workout_NumberOfTimesCompleted]  DEFAULT ((0)) FOR [NumberOfTimesCompleted]
GO

ALTER TABLE [dbo].[Workout] ADD  CONSTRAINT [DF_Workout_DateOfLastCompletion]  DEFAULT (getdate()) FOR [DateOfLastCompletion]
GO

ALTER TABLE [dbo].[Workout]  WITH CHECK ADD  CONSTRAINT [FK_ExcerciseNameToWorkout] FOREIGN KEY([ExerciseID])
REFERENCES [dbo].[Exercise] ([ExcerciseID])
GO

ALTER TABLE [dbo].[Workout] CHECK CONSTRAINT [FK_ExcerciseNameToWorkout]
GO

ALTER TABLE [dbo].[Workout]  WITH CHECK ADD  CONSTRAINT [FK_ExerciseTypeToWorkout] FOREIGN KEY([ExerciseTypeID])
REFERENCES [dbo].[ExerciseType] ([ExerciseTypeID])
GO

ALTER TABLE [dbo].[Workout] CHECK CONSTRAINT [FK_ExerciseTypeToWorkout]
GO

ALTER TABLE [dbo].[Workout]  WITH CHECK ADD  CONSTRAINT [FK_WorkoutToPerson] FOREIGN KEY([PersonID])
REFERENCES [dbo].[Person] ([PersonID])
GO

ALTER TABLE [dbo].[Workout] CHECK CONSTRAINT [FK_WorkoutToPerson]
GO

Ответ или решение

Проблема, с которой вы столкнулись — это ошибка во время выполнения хранимой процедуры в SQL Server Management Studio 2022, связанная с преобразованием строкового значения в тип данных uniqueidentifier. Этот тип ошибки может возникнуть по нескольким причинам, что мы и рассмотрим в данной статье.

1. Проблема с исходным кодом

Из вашего описания видно, что проблема возникает, когда вы выполняете хранимую процедуру, а не при её компиляции или разборе, что указывает на наличие неявного преобразования типов данных в момент выполнения. Ниже приведён код, с которым вы работаете:

DECLARE IndexCursor CURSOR FOR
    SELECT PersonID AS NewUserID
    FROM Person as tblUser

OPEN IndexCursor
FETCH NEXT FROM IndexCursor INTO @UserID

INSERT INTO Workout (PersonID, ExerciseID, ExerciseTypeID)
    SELECT *
    FROM Exercise A
    WHERE NOT EXISTS (SELECT @UserID, A.ExcerciseID, A.ExerciseTypeID
                      FROM Workout B
                      WHERE A.ExcerciseID = B.ExerciseID)

Здесь можно выделить несколько ключевых моментов:

  • @UserID — это переменная типа uniqueidentifier, которая должна быть совместима с полем PersonID в таблице Workout.
  • В данном случае ошибка преобразования может быть связана с условием в предложении WHERE. Давайте рассмотрим его более подробно.

2. Анализ предложения WHERE

Ваша проверка в условии WHERE NOT EXISTS может вызывать проблемы из-за неправильно указанных типов данных или даже ошибок в написании. В вашем коде есть опечатка: вы пишете A.ExcerciseID вместо A.ExerciseID. Это может приводить к ошибкам, когда SQL Server пытается определить, существует ли поле с указанным именем, и, возможно, не может сопоставить его с типом данных.

3. Проверка корректности индексов и уникальности

Поскольку оба столбца в вашем условии являются uniqueidentifier, важно также убедиться, что данные в столбцах совпадают по типу и значению. Необходимо проверить целостность данных:

  • Убедитесь, что данные, хранящиеся в таблице Workout для PersonID, соответствуют данным, получаемым из tblUser.
  • Убедитесь, что переменная @UserID, полученная из курсора, корректно загружается и используется.

4. Подходы к исправлению

Для дальнейшей диагностики и устранения проблемы, рассмотрите следующие шаги:

  1. Проверка значений переменной: Перед установкой в @UserID, добавьте временный отладочный код, чтобы проверить, действительно ли @UserID содержит значения типа uniqueidentifier.

    PRINT CAST(@UserID AS VARCHAR(36));
  2. Замена NOT EXISTS: Попробуйте переписать условие WHERE без использования SELECT с подзапросом, например, с помощью JOIN, чтобы избежать неявных преобразований.

  3. Упрощенный запрос: Упростите ваш запрос и поэкспериментируйте с отдельными частями, чтобы изолировать проблему.

5. Заключение

Ошибки типа "не удалось преобразовать строку в uniqueidentifier" могут быть достаточно запутанными и часто возникают из-за несовпадения типов данных или ошибочного использования переменных. При выполнении представленных выше шагов вы сможете более точно определить причину возникновения проблемы и устранить её.

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

Оцените материал
Добавить комментарий

Капча загружается...