Sql server Msg 102,级别15,状态1,程序顺序添加,第13行[批处理起始行0]靠近'的语法不正确@Id';

Sql server Msg 102,级别15,状态1,程序顺序添加,第13行[批处理起始行0]靠近'的语法不正确@Id';,sql-server,Sql Server,我创建了用于在“order”表中插入记录的存储过程。我正在尝试从变量@id中的另一个数据库中获取Order表的最大id 模式如下: CREATE PROCEDURE order_add @orderstatus nvarchar(1000), @paymentstatus nvarchar(1000), @Customer nvarchar(1000), @createdon nvarchar(1000), @ord

我创建了用于在“order”表中插入记录的存储过程。我正在尝试从变量
@id
中的另一个数据库中获取
Order
表的最大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;
在执行此存储过程时,出现以下错误:

Msg 102,15级,状态1,程序顺序添加,第13行[批处理起始行0]
“@Id”附近的语法不正确


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

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

      此外,您还需要在代码中提供指导。假设您在一个有多个成员的团队中工作,并且其中至少有一个成员具有丰富的经验。您的团队应该进行代码审查,以提高代码编写的总体质量,提高团队内部的业务知识水平,并识别编码错误。这个过程应该抓住很多问题,我将提到其中一些问题

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

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

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

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

      是否应该
      [Database2].dbo.“订单”
      [Database2].dbo.[Order]