存储过程错误:“将数据类型nvarchar转换为uniqueidentifier时出错”

时间:2017-10-25 11:34:14

标签: sql sql-server-2008 tsql stored-procedures stored-functions

所以我是创建SP的新手,现在我正在尝试创建一个SP,将值插入我的表格报告中。

CREATE TABLE Report (
    ID UNIQUEIDENTIFIER PRIMARY KEY NOT NULL,
    STAFF VARCHAR(1000)NOT NULL,
    EMAIL VARCHAR(1000)NOT NULL,
    LASTCHANGE DATE NOT NULL
)

CREATE PROCEDURE spInsertOrUpdate(
    @ID UNIQUEIDENTIFIER,
    @STAFF VARCHAR(1000),
    @EMAIL VARCHAR(1000),
    @LASTCHANGE DATETIME
) AS
BEGIN
    INSERT INTO Report(ID, STAFF, EMAIL, LASTCHANGE)
        VALUES(@ID, @STAFF, @EMAIL, @LASTCHANGE)
END

EXEC spInsertOrUpdate NEWID, 'Evlyn Dawson', 'evdawson@gmail.com', GETDATE

正确执行SP后跟随错误:

  

Msg 8114,Level 16,State 5,Procedure spInsertOrUpdate,Line 0将数据类型nvarchar转换为uniqueidentifier时出错

有人可以帮我解决这个问题吗?

4 个答案:

答案 0 :(得分:1)

我首先要正确调用函数:

EXEC spInsertOrUpdate NEWID(), 'Evlyn Dawson', 'evdawson@gmail.com', GETDATE();

NEWID()GETDATE()是函数,所以你需要括号。

但是,我认为缺少括号会导致该特定错误。您需要先设置变量,然后将它们用于exec

编辑:

更好的方法是自动设置ids和日期

CREATE TABLE Report (
    ID UNIQUEIDENTIFIER PRIMARY KEY NOT NULL DEFAULT NEWID(),
    STAFF VARCHAR(1000) NOT NULL,
    EMAIL VARCHAR(1000) NOT NULL,
    LASTCHANGE DATE NOT NULL DEFAULT GETDATE()
);

CREATE PROCEDURE spInsertOrUpdate (
    @STAFF VARCHAR(1000),
    @EMAIL VARCHAR(1000)
) AS
BEGIN
    INSERT INTO Report(STAFF, EMAIL)
        VALUES (@STAFF, @EMAIL)
END;

EXEC spInsertOrUpdate 'Evlyn Dawson', 'evdawson@gmail.com';

我也不鼓励您使用唯一标识符作为表中的主键。它们效率很低,因为它们可能导致页面碎片化。请改用identity列。

答案 1 :(得分:1)

此错误消息有点像一个疯狂的追逐,问题是NEWID()GETDATE()都是函数,所以需要括号。不幸的是,您无法将函数作为参数传递给存储过程,因此您首先需要将值分配给变量:

DECLARE @ID UNIQUEIDENTIFIER = NEWID(),
        @Date DATE = GETDATE();

EXEC #spInsertOrUpdate @ID, 'Evlyn Dawson', 'evdawson@gmail.com', @Date;

除此之外,a UNIQUEIDENTIFIER column is a very poor choice for a clustering key

答案 2 :(得分:1)

因此,如果您只是使用getdate和newid调用存储过程,为什么不将它们作为默认值添加到您的表中?

表格

  CREATE TABLE [dbo].[Report](
    [ID] [uniqueidentifier] NOT NULL CONSTRAINT [DF_Report_ID]  DEFAULT (newid()),
    [STAFF] [varchar](1000) NOT NULL,
    [EMAIL] [varchar](1000) NOT NULL,
    [LASTCHANGE] [datetime] NOT NULL CONSTRAINT [DF_Report_LASTCHANGE]  DEFAULT (getdate()),
 CONSTRAINT [PK__Report__3214EC27D2D8BF72] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

<强>程序

create PROCEDURE spInsertOrUpdate(

@STAFF VARCHAR(1000),
@EMAIL VARCHAR(1000)

) AS
BEGIN
INSERT INTO Report(STAFF, EMAIL)
    VALUES(@STAFF, @EMAIL)
END

执行声明

EXEC spInsertOrUpdate  'Evlyn Dawson', 'evdawson@gmail.com'

修改 另请注意,您的lastchanged列的类型为DATE,但是如果您想要带有时间戳的日期,则应使用datetime

答案 3 :(得分:0)

感谢您的帮助。我终于在SP中找到了正确的方法 现在我对SP有了正确的认识。这就是我解决问题的方法

CREATE PROCEDURE spInsertOrUpdate(@STAFF VARCHAR(1000),@EMAIL VARCHAR(1000),@CARS VARCHAR(1000))

AS
BEGIN
INSERT INTO Report(ID,STAFF,EMAIL,CARS,LASTCHANGE)
VALUES(NEWID(),@STAFF,@EMAIL,@CARS,GETDATE())
END

EXEC spInsertOrUpdate 'Evlyn Dawson','evdawson@gmail.com','Ferrari'

请注意,我还有一个CARS专栏