消息102,级别15,状态1,过程order_add,行13 [批处理开始行0]'@Id'附近的语法不正确

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

我创建了用于在'order'表中插入记录的存储过程。我试图从变量Order中的另一个数据库中获取@Id表的最大id。

架构如下:

CREATE PROCEDURE order_add
        @orderstatus nvarchar(1000),
        @paymentstatus nvarchar(1000),
        @Customer nvarchar(1000),
        @createdon nvarchar(1000),
        @ordertotal nvarchar(1000)
AS
    DECLARE @Id int;
BEGIN
    SELECT MAX(Id) 
    INTO @Id 
    FROM [Database2].dbo."Order";

    INSERT INTO Customer 
    VALUES(@Id, @orderstatus, @paymentstatus, @Customer, @createdon, @ordertotal);
END;

当我执行此存储过程时,我收到此错误:

消息102,级别15,状态1,过程order_add,行13 [批处理开始行0] '@Id'附近的语法不正确。

我该怎么做才能解决这个问题?

sql-server
2个回答
1
投票

您的程序具有SELECT语句的时尚语法:

select @Id = max(Id) 
from [Database2].dbo.Order

insert into Customer (id, orderstatus, paymentstatus, Customer, createdon, ordertotal)
       values(@Id, @orderstatus, @paymentstatus, @Customer, @createdon, @ordertotal
             );

注意 :

  • 使用insert into语句时,始终明确限定所有列名称。

0
投票

你有一个“解决”这个问题的答案。但请停下来思考一下你的代码。考虑数据库服务器中对象的层次结构。您在特定数据库中创建过程。使用数据库名称限定表名称是危险的 - 即使该名称与创建过程的名称相同。为什么?因为有人最终会想要创建这个数据库的副本。可能用于测试,灾难恢复等。现在您的过程将失败或无法产生正确的结果。

此外,您需要在代码中获得指导。大概你在一个拥有多个成员的团队中工作,其中至少有一个成员具有丰富的经验。您的小组应该进行代码审查,以提高代码编写的质量,提高组内的业务知识水平,并识别编码错误。这个过程应该抓住很多问题,其中一些我会提到。

您应该使用SET而不是SELECT来分配标量变量。为什么?因为当查询找不到行时,存在细微且显着的差异。在这种情况下,SET将为变量赋值NULL,而SELECT将保持不变。更多here

您还需要考虑数据类型。使用正确的,不要只是将所有内容定义为字符串 - 尤其是非常大的字符串。我猜你的大多数参数都不应该是nvarchar - 当然不包含1000个字符。

为什么在第一个select语句中使用双引号?如果你遵循对象名称的规则(你应该),你不需要分隔它们(这是双引号的作用)。保持一致并遵守规则。再次 - 不要使用数据库名称限定表名,除非您绝对打算这样做有充分理由。如果您打算这样做,那么请使用同义词。这将使某人的生活更轻松,并给你良好的业力。

最后,始终指定您在insert语句中填充的列的列表。不要 - 重复不 - 养成省略的懒惰习惯。为什么?列的顺序可能会发生变化 - 尽管看起来不太可能。可能会添加一个带有默认值的附加列。假设在这种情况下应使用默认值,您现在必须更改语句。通过指定列列表,您的代码将在添加列后继续正常工作。

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