从字符串转换为uniqueidentifier时再次转换失败问题

问题描述 投票:0回答:1

无论如何,这是针对 SQL Server 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
,并抓取它以便可以将其用于填充锻炼表。其他数据已经在练习表中了。

这个想法是,如果添加了一项锻炼,它会将该锻炼添加到数据库中每个人的锻炼中。所有字段和变量都设置为 uniqueidentifier,所以我真的不知道为什么它必须将任何内容转换为它应该已经设置的内容。

我确实发现 where 子句的两个字段存在差异,但我不知道如何修复它。

B.ExerciseID
有默认值 (
newid()
),
A.exercise
列没有。

我知道我的“exercise”有拼写错误,我需要去修改这些错误。哈哈

我在所有出现的情况下都尝试过

CAST
CONVERT
上的
@UserID
。我已经在
CAST
A.Exercise
上依次和同时尝试了
B.Exercise
。我不断地用谷歌搜索不同的想法。我已经注释掉了部分代码,以缩小导致问题的实际行范围(直到我这样做,我才意识到
@UserID
变量实际上并没有导致问题)

更新:

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)[PRIMARY]
) ON [PRIMARY]


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)
) 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


USE [WorkoutTracker]
GO

/****** Object:  Table [dbo].[Exercise]    Script Date: 10/27/2024 10:37:47 PM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Exercise](
    [ExcerciseID] [uniqueidentifier] NOT NULL,
    [ExerciseName] [varchar](50) NOT NULL,
    [ExerciseTypeID] [uniqueidentifier] NOT NULL,
 CONSTRAINT [PK_Exercise] PRIMARY KEY CLUSTERED 
(
    [ExcerciseID] 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

ALTER TABLE [dbo].[Exercise] ADD  CONSTRAINT [DF_Exercise_ExcerciseID]  DEFAULT (newid()) FOR [ExcerciseID]
GO

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

ALTER TABLE [dbo].[Exercise] CHECK CONSTRAINT [FK_ExcerciseTypeToExcercise]
GO
sql sql-server stored-procedures type-conversion runtime-error
1个回答
0
投票

玩完这个之后我选择了一个完全不同的方向。我使用 if 语句来检查丢失的记录,然后如果有任何记录,我会逐步收集信息。然后将其全部插入到最后的表中。这是成品。我知道它很丑陋,并且希望得到有关如何减少混乱的建议,例如我使用了超过三次的同一个 select 子句。

USE [WorkoutTracker]
GO
/****** Object:  StoredProcedure [dbo].[UpdateUserWorkouts]    Script Date: 10/27/2024 10:28:37 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[UpdateUserWorkouts]
    -- Add the parameters for the stored procedure here
AS
    SET NOCOUNT ON;

    IF EXISTS (
        SELECT    Exercise.ExcerciseID, Exercise.ExerciseTypeID     
        FROM            dbo.Exercise LEFT OUTER JOIN
                                 dbo.Workout ON  dbo.Exercise.ExcerciseID = dbo.Workout.ExerciseID
        WHERE        (dbo.Workout.WrokoutID IS NULL)
        )
    BEGIN

    

    DECLARE @UserID uniqueidentifier
    DECLARE @ExerciseID uniqueidentifier
    DECLARE @ExerciseTypeID uniqueidentifier

    SET @ExerciseID = (SELECT Exercise.ExcerciseID FROM dbo.Exercise LEFT OUTER JOIN dbo.Workout ON  dbo.Exercise.ExcerciseID = dbo.Workout.ExerciseID WHERE (dbo.Workout.WrokoutID IS NULL))
    SET @ExerciseTypeID = (SELECT Exercise.ExerciseTypeID FROM dbo.Exercise LEFT OUTER JOIN dbo.Workout ON  dbo.Exercise.ExcerciseID = dbo.Workout.ExerciseID WHERE (dbo.Workout.WrokoutID IS NULL))

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

    OPEN IndexCursor
    FETCH NEXT FROM IndexCursor INTO @UserID


        WHILE @@FETCH_STATUS = 0
        BEGIN
            INSERT INTO Workout
                (
                    PersonID
                    , ExerciseID
                    , ExerciseTypeID
                )
            VALUES 
                (
                    @UserID
                    , @ExerciseID
                    , @ExerciseTypeID
                )

            FETCH NEXT FROM IndexCursor INTO @UserID

        END

    Close IndexCursor
    DEALLOCATE IndexCursor

    END
© www.soinside.com 2019 - 2024. All rights reserved.